mgiay/CVE-2026-25589-25588-25243-23631-23479-REDIS
GitHub: mgiay/CVE-2026-25589-25588-25243-23631-23479-REDIS
针对 Redis 五个高危 RCE 漏洞(CVE-2026-23479/25243/25588/25589/23631)的自动化检测与免重启修复脚本,提供 ACL 拦截、命令禁用、配置加固等多种缓解方案。
Stars: 0 | Forks: 0
# Redis 5 个 CVE 测试与修复指南(截至 2026.05.08)
## 目录
1. [概述](#tổng-quan)
2. [受影响版本](#phiên-bản-bị-ảnh-hưởng)
3. [各 CVE 详细信息](#chi-tiết-từng-cve)
- [CVE-2026-23479 — Unblock Client Flow 中的 Use-after-free](#cve-2026-23479)
- [CVE-2026-25243 — RESTORE 中的 Invalid Memory Access](#cve-2026-25243)
- [CVE-2026-25588 — 涉及 RedisTimeSeries Module 的 RESTORE](#cve-2026-25588)
- [CVE-2026-25589 — 涉及 RedisBloom Module 的 RESTORE](#cve-2026-25589)
- [CVE-2026-23631 — 通过 Master-Replica Sync 触发的 Lua Use-After-Free](#cve-2026-23631)
4. [脚本使用指南](#hướng-dẫn-sử-dụng-script)
5. [通用修复方法](#các-phương-pháp-khắc-phục-chung)
6. [风险评估 — 内部 Redis 系统 / Sentinel](#đánh-giá-rủi-ro--hệ-thống-redis-nội-bộ--sentinel)
7. [ACL 参考](#acl-reference)
8. [定期检查流程](#quy-trình-kiểm-tra-định-kỳ)
9. [常见问题解答 (FAQ)](#câu-hỏi-thường-gặp)
## 概述
2026 年 5 月 5 日,Redis Ltd. 发布了关于 5 个严重安全漏洞的安全公告,这些漏洞影响 **所有 Redis OSS/CE 版本**。如果被成功利用,所有这些 CVE 都可能导致 **远程代码执行 (RCE)**。
| # | CVE 编号 | CVSS | 严重程度 | 漏洞类型 | 利用条件 |
| --- | -------------- | ---- | -------- | --------------------- | ---------------------------------------------- |
| 1 | CVE-2026-23479 | 7.7 | HIGH | Use-After-Free | 已认证,有运行 blocking command 的权限 |
| 2 | CVE-2026-25243 | 7.7 | HIGH | Invalid Memory Access | 已认证,有运行 RESTORE 的权限 |
| 3 | CVE-2026-25588 | 7.7 | HIGH | Invalid Memory Access | 已认证,有运行 RESTORE 的权限 + RedisTimeSeries module |
| 4 | CVE-2026-25589 | 7.7 | HIGH | Invalid Memory Access | 已认证,有运行 RESTORE 的权限 + RedisBloom module |
| 5 | CVE-2026-23631 | 6.1 | MEDIUM | Use-After-Free | 已认证,`replica-read-only` = disabled 的 replica |
## 受影响版本
### Redis OSS/CE — 打补丁前的所有版本
| 版本线 | 已修复版本(最低) |
| ------- | ----------------------------- |
| 6.2.x | **6.2.22** |
| 7.2.x | **7.2.14** |
| 7.4.x | **7.4.9** |
| 8.2.x | **8.2.6** |
| 8.4.x | **8.4.3** |
| 8.6.x | **8.6.3** |
### Module — 已修复版本
| Module | 最低版本 |
| --------------- | --------------------------- |
| RedisTimeSeries | 1.12.14 / 1.10.24 / 1.8.23 |
| RedisBloom | 2.8.20 / 2.6.28 / 2.4.23 |
### Redis Software (Enterprise)
| 版本 | 补丁版本 |
| -------- | ----------- |
| 8.0.6 | 8.0.10-64 |
| 7.22.2 | 7.22.2-79 |
| 7.8.6 | 7.8.6-253 |
| 7.4.6 | 7.4.6-279 |
| 7.2.4 | 7.2.4-153 |
### Redis Cloud
所有 Redis Cloud 部署在发布公告时已 **自动完成修补**。
## 各 CVE 详细信息
### CVE-2026-23479
| 属性 | 值 |
| ------------- | --------------------------------------------------------------- |
| **标题** | Unblock Client Flow 中的 Use-After-Free |
| **CVSS 4.0** | **7.7 (HIGH)** |
| **CWE** | CWE-416 (Use After Free) |
| **向量** | `AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N` |
| **条件** | 经过身份验证的攻击者,拥有执行 blocking commands 的权限 |
| **影响范围** | 所有 Redis OSS/CE,Redis Software <= 8.0.6 |
#### 技术描述
当一个被阻塞的 (blocked) client(例如在 `BLPOP` 中等待)在重新执行被阻塞的命令期间被驱逐时,`processCommandAndResetClient` 函数可能会返回错误。当前代码未能正确处理这种情况,导致指针引用了已释放的内存区域,从而引发 use-after-free。攻击者可以利用此 UAF 漏洞执行远程代码 (RCE)。
#### 识别标志
- Redis 服务器崩溃,且堆栈信息中包含与 `unblock client` 和 `processCommandAndResetClient` 相关的函数
- `redis-server` 进程执行未知命令
- 到 Redis 实例的未经授权的网络连接
#### 受影响的 blocking 命令
```
BLPOP, BRPOP, BRPOPLPUSH, BLMOVE, BLMPOP,
BZPOPMIN, BZPOPMAX, BZMPOP,
WAIT, WAITAOF,
XREAD, XREADGROUP
```
#### 修复方法(不升级)
**方法 1 — 通过 ACL 进行拦截(推荐):**
```
# 阻止所有 blocking 命令组
redis-cli ACL SETUSER default -@blocking
# 或者阻止特定的各个命令
redis-cli ACL SETUSER default -BLPOP -BRPOP -BRPOPLPUSH -BLMOVE -BLMPOP \
-BZPOPMIN -BZPOPMAX -BZMPOP \
-WAIT -WAITAOF \
-XREAD -XREADGROUP
# 保存 ACL
redis-cli ACL SAVE
```
**方法 2 — 通过 rename-command 禁用(需要重启 Redis):**
```
# 添加至 redis.conf:
rename-command BLPOP ""
rename-command BRPOP ""
rename-command BRPOPLPUSH ""
rename-command BLMOVE ""
rename-command BLMPOP ""
rename-command BZPOPMIN ""
rename-command BZPOPMAX ""
rename-command BZMPOP ""
rename-command WAIT ""
rename-command WAITAOF ""
rename-command XREAD ""
rename-command XREADGROUP ""
```
**方法 3 — 开启 protected-mode 并限制连接:**
```
redis-cli CONFIG SET protected-mode yes
# 在 redis.conf 中:
protected-mode yes
bind 127.0.0.1
```
### CVE-2026-25243
| 属性 | 值 |
| ------------- | -------------------------------------------------------------------------- |
| **标题** | RESTORE Command 中的 Invalid Memory Access |
| **CVSS 4.0** | **7.7 (HIGH)** |
| **CWE** | CWE-20 (Improper Input Validation) + CWE-122 (Heap Buffer Overflow) |
| **向量** | `AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N` |
| **条件** | 经过身份验证的攻击者,拥有执行 RESTORE 的权限 |
| **影响范围** | 所有 Redis OSS/CE,Redis Software <= 8.0.6 |
#### 技术描述
该漏洞包含 2 个子问题:
1. Redis 核心中的 **Double-free**(由 Emil Lerner 发现)— RESTORE 在处理特制的序列化 payload 时,导致同一个指针被释放两次。
2. VectorSets 中的 **Integer overflow 和 Out-Of-Bounds read**(由 Joseph Surin 发现)— 特制的 payload 引发整数溢出,导致越界读写已分配的内存。
通过身份验证的攻击者可发送特制的 `RESTORE` payload 来利用上述漏洞,这可能会导致 `redis-server` 进程上下文中发生 RCE。
#### 识别标志
- Redis 服务器异常崩溃
- 文件系统发生改变(特别是在 Redis 的 RDB/AOF/配置 目录中)
- 与 Redis 实例之间建立未经授权的传入或传出网络连接
- Redis 配置文件被修改
#### 修复方法(不升级)
**方法 1 — 通过 ACL 拦截 RESTORE(推荐):**
```
# 阻止 RESTORE 命令
redis-cli ACL SETUSER default -restore
# 或者阻止所有危险命令组
redis-cli ACL SETUSER default -@dangerous
redis-cli ACL SAVE
```
**方法 2 — 禁用 RESTORE(需要重启 Redis):**
```
# 添加至 redis.conf:
rename-command RESTORE ""
```
**方法 3 — 为应用程序创建独立的 ACL 用户:**
```
# 为应用程序创建仅具有基本读/写权限的用户
redis-cli ACL SETUSER app_user on >StrongPass123 ~* \
+@read +@write \
-@dangerous \
-@admin \
-@scripting \
-@blocking \
-restore \
-debug
redis-cli ACL SAVE
```
### CVE-2026-25588
| 属性 | 值 |
| ------------- | ----------------------------------------------------------------------- |
| **标题** | 涉及 RedisTimeSeries Module 的 RESTORE 中的 Invalid Memory Access |
| **CVSS 4.0** | **7.7 (HIGH)** |
| **CWE** | CWE-20 + CWE-122 |
| **向量** | `AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N` |
| **条件** | 已认证 + 拥有 RESTORE 权限 + **已加载 RedisTimeSeries module** |
| **影响范围** | Redis OSS/CE + RedisTimeSeries module |
#### 技术描述
当在已加载 **RedisTimeSeries module** 的实例上使用 `RESTORE` 命令时,特制的序列化 payload 可能会在处理 time-series 数据的过程中触发非法的内存访问。该漏洞存在于 RedisTimeSeries 模块对 RESTORE payload 的数据反序列化方式中。
#### 识别标志
- Redis 崩溃,堆栈信息与 RedisTimeSeries 模块相关
- 当前已加载 RedisTimeSeries 模块(`MODULE LIST` 显示 timeseries)
- redis-server 执行了非预期的命令
#### 修复方法(不升级)
**方法 1 — 通过 ACL 拦截 RESTORE:**(同 CVE-2026-25243)
```
redis-cli ACL SETUSER default -restore
redis-cli ACL SAVE
```
**方法 2 — 移除 RedisTimeSeries 模块(如果不需要):**
```
redis-cli MODULE UNLOAD timeseries
```
然后从 `redis.conf` 中删除以下行:
```
loadmodule /path/to/redistimeseries.so
```
**方法 3 — 仅升级模块(不升级 Redis):**
下载已修补的模块版本:
- RedisTimeSeries **1.12.14**(适用于 1.12 版本线)
- RedisTimeSeries **1.10.24**(适用于 1.10 版本线)
- RedisTimeSeries **1.8.23**(适用于 1.8 版本线)
```
# 用新版本替换旧的 .so 文件
# 然后重启 Redis 或:
redis-cli MODULE UNLOAD timeseries
redis-cli MODULE LOAD /path/to/new/redistimeseries.so
```
### CVE-2026-25589
| 属性 | 值 |
| ------------- | ------------------------------------------------------------------------------------ |
| **标题** | 涉及 RedisBloom Module 的 RESTORE 中的 Invalid Memory Access |
| **CVSS 4.0** | **7.7 (HIGH)** |
| **CWE** | CWE-20 + CWE-122 + CWE-787 (Out-of-Bounds Write) + CWE-190 (Integer Overflow) |
| **向量** | `AV:N/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N` |
| **条件** | 已认证 + 拥有 RESTORE 权限 + **已加载 RedisBloom module** |
| **影响范围** | Redis OSS/CE + RedisBloom module |
#### 技术描述
该漏洞包含 RedisBloom 模块在处理 RESTORE payload 时的多个子问题:
1. **Out-Of-Bounds read/write** (Daniel Firer) — 在已分配的内存范围之外进行读写
2. **Integer overflow, heap buffer overflow, 和 OOB read/write** (Joseph Surin) — 整数溢出导致堆缓冲区溢出
当加载了 RedisBloom 模块时,攻击者可以发送特制的 RESTORE payload,在反序列化 Bloom filter、Cuckoo filter、Count-Min Sketch 或 Top-K 数据期间利用这些漏洞。
#### 识别标志
- Redis 崩溃,堆栈信息与 RedisBloom 模块相关
- 当前已加载 RedisBloom 模块(`MODULE LIST` 显示 bf/bloom)
- Bloom filter 中的数据损坏或发生异常变化
#### 修复方法(不升级)
**方法 1 — 通过 ACL 拦截 RESTORE:**(同 CVE-2026-25243)
```
redis-cli ACL SETUSER default -restore
redis-cli ACL SAVE
```
**方法 2 — 移除 RedisBloom 模块(如果不需要):**
```
redis-cli MODULE UNLOAD bf
```
然后从 `redis.conf` 中删除以下行:
```
loadmodule /path/to/redisbloom.so
```
**方法 3 — 仅升级模块(不升级 Redis):**
下载已修补的模块版本:
- RedisBloom **2.8.20**(适用于 2.8 版本线)
- RedisBloom **2.6.28**(适用于 2.6 版本线)
- RedisBloom **2.4.23**(适用于 2.4 版本线)
```
redis-cli MODULE UNLOAD bf
redis-cli MODULE LOAD /path/to/new/redisbloom.so
```
### CVE-2026-23631
| 属性 | 值 |
| ------------- | ------------------------------------------------------------------- |
| **标题** | 通过 Master-Replica Synchronization 触发的 Lua Use-After-Free |
| **CVSS 4.0** | **6.1 (MEDIUM)** |
| **CWE** | CWE-416 (Use After Free) |
| **向量** | `AV:N/AC:HAT:N/PR:L/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N` |
| **条件** | 已认证 + **replica** 且 `replica-read-only` = **disabled** |
| **影响范围** | 所有启用了 Lua scripting 的 Redis OSS/CE,仅在 replica 上触发 |
| **代号** | "DarkReplica" (Yoni Shiraz, Wiz Zeroday Cloud) |
#### 技术描述
通过身份验证的攻击者可以利用 master-replica 同步机制发送特殊的 Lua script,从而在 replica 上的 Lua 引擎中触发 use-after-free。
**关键条件:** 该 Bug **仅影响**配置了 `replica-read-only disabled` 的 replica(即 replica 可写)。这 **不是** 默认配置——默认的 `replica-read-only` 为 `yes`。
如果 replica 配置为只读模式(默认),则实例 **不受影响**。
#### 识别标志
- replica 上的 Redis 崩溃,堆栈信息来自 Lua 引擎
- replica 上的配置为 `replica-read-only` = `no`
- 在 replica 上执行了未知命令
- 到 replica 的未经授权的网络连接
#### 修复方法(不升级)
**方法 1 — 开启 replica-read-only(推荐,此为默认设置):**
```
# Runtime
redis-cli CONFIG SET replica-read-only yes
# 在 redis.conf 中:
replica-read-only yes
```
**方法 2 — 通过 ACL 拦截 Lua scripting:**
```
redis-cli ACL SETUSER default -@scripting
redis-cli ACL SETUSER default -eval -evalsha -script -function -fcall -fcall_ro
redis-cli ACL SAVE
```
**方法 3 — 禁用 Lua commands(需要重启 Redis):**
```
# 添加至 redis.conf:
rename-command EVAL ""
rename-command EVALSHA ""
rename-command SCRIPT ""
rename-command FUNCTION ""
rename-command FCALL ""
rename-command FCALL_RO ""
```
## 脚本使用指南
### 工作原理
- **无参数** → 显示使用帮助
- **`--scan`** → 诊断并检查所有 CVE
- **`--fix-...`** → 针对特定 CVE 应用修复措施
```
$ ./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh
→ hiển thị banner + HELP + thoát
```
### 系统要求
- **操作系统:** Linux (Ubuntu, Debian, CentOS, RHEL, ...)
- **工具:** `redis-cli`(通常包含在 `redis-tools` 或 `redis` 包中)
- **权限:** 对 `redis.conf` 文件的读写权限(用于修复操作)
- **连接:** 能够连通待检查的 Redis 实例的网络
### 安装 redis-cli(如果尚未安装)
```
# Ubuntu/Debian
sudo apt update && sudo apt install -y redis-tools
# CentOS/RHEL 7
sudo yum install -y redis
# CentOS/RHEL 8+/Fedora
sudo dnf install -y redis
# 或者从 source
wget https://download.redis.io/releases/redis-stable.tar.gz
tar xzf redis-stable.tar.gz
cd redis-stable && make redis-cli
sudo cp src/redis-cli /usr/local/bin/
```
### 使用方法
#### 1. 查看帮助
```
# 授予可执行权限
chmod +x CVE-2026-25589-25588-25243-23631-23479-REDIS.sh
# 无参数运行 → 显示 help
./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh
# 或者显式指定
./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --help
```
#### 2. 扫描检查所有 CVE(诊断)
```
# 本地 Redis
./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --scan
# 远程 Redis
./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --scan \
-H 192.168.1.100 -p 6379 -a "your_password"
# 使用 ACL 用户
./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --scan \
-H 10.0.0.50 -p 6380 -u admin -a "admin_password"
# 通过 Unix socket
./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --scan \
-s /var/run/redis/redis-server.sock
# 附带导出报告
./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --scan \
-o redis_cve_report_$(date +%Y%m%d).txt
```
#### 3. 针对单个 CVE 进行修复
```
# 修复特定 CVE
./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --fix-cve-23479
./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --fix-cve-25243 -H 10.0.0.1 -a mypassword
./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --fix-cve-25588
./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --fix-cve-25589
./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --fix-cve-23631 -c /etc/redis/redis.conf
```
#### 4. 按组快速修复(推荐)
```
# 阻止 RESTORE → 防护 3/5 个 CVE (25243 + 25588 + 25589)
./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --fix-restore
# 阻止 blocking commands → 防护 CVE-2026-23479
./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --fix-blocking
# 阻止 Lua + 启用 replica-read-only → 防护 CVE-2026-23631
./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --fix-lua
```
#### 5. 修复所有漏洞
```
# 修复所有 CVE (带配置备份)
./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --fix-all
# 使用独立配置文件修复所有
./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --fix-all \
-c /etc/redis/redis.conf
# 修复所有无备份 (不推荐)
./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --fix-all --no-backup
# 修复所有远程 Redis
./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --fix-all \
-H 10.0.0.1 -p 6379 -a mypassword
```
### 完整参数列表
#### 操作参数 (ACTION) — 必填
| 参数 | 功能 | 保护的 CVE 数量 |
| ------------------ | ------------------------------------------ | ----------------------------- |
| *(无参数)* | 显示使用帮助 | — |
| `--scan` | 扫描并诊断所有 5 个 CVE | — |
| `--fix-all` | 修复所有 CVE | **5/5** |
| `--fix-restore` | **[快速]** 仅拦截 RESTORE 命令 | **3/5** (25243, 25588, 25589) |
| `--fix-blocking` | **[快速]** 仅拦截 blocking commands | **1/5** (23479) |
| `--fix-lua` | **[快速]** 拦截 Lua + 开启 replica-read-only | **1/5** (23631) |
| `--fix-cve-23479` | 修复 CVE-2026-23479 | 1/5 |
| `--fix-cve-25243` | 修复 CVE-2026-25243 | 1/5 |
| `--fix-cve-25588` | 修复 CVE-2026-25588 | 1/5 |
| `--fix-cve-25589` | 修复 CVE-2026-25589 | 1/5 |
| `--fix-cve-23631` | 修复 CVE-2026-23631 | 1/5 |
#### 连接参数
| 参数 | 描述 | 默认值 |
| -------------------- | ------------------- | ------------- |
| `-H, --host HOST` | Redis 主机地址 | `127.0.0.1` |
| `-p, --port PORT` | Redis 端口 | `6379` |
| `-a, --pass PASS` | Redis 密码 | *(空)* |
| `-u, --user USER` | ACL 用户名 | `default` |
| `-s, --socket PATH` | Unix socket 路径 | *(空)* |
#### 附加参数
| 参数 | 描述 | 默认值 |
| -------------------- | ------------------------------------------- | ----------------------- |
| `-h, --help` | 显示帮助 | — |
| `-c, --config FILE` | redis.conf 路径 | `/etc/redis/redis.conf` |
| `-o, --output FILE` | 将报告输出到文件(仅适用于 `--scan`) | *(空)* |
| `--redis-cli PATH` | redis-cli 二进制文件路径 | `redis-cli`(来自 PATH)|
| `--no-backup` | 修改前不备份配置文件 | `false` |
### 退出代码
| 代码 | 含义 |
| ---- | ---------------------------------------------------- |
| `0` | 成功 — 未检测到 CVE 或修复已完成 |
| `1` | 错误:未找到 redis-cli 或无法连接 |
| `2` | `--scan` 检测到至少 1 个 CVE — 需要修复 |
### 扫描时的输出结果 (`--scan`)
```
╔══════════════════════════════════════════════════════════════════════╗
║ REDIS CVE SCANNER & MITIGATION TOOL ║
╚══════════════════════════════════════════════════════════════════════╝
[*] THONG TIN REDIS INSTANCE
Host:Port : 127.0.0.1:6379
Version : 7.2.5
Mode : standalone
Role : master
Modules : timeseries bf
═══════════════════════════════════════════════════════════════════════
[1/5] CVE-2026-23479 - Use-after-free trong Unblock Client Flow
CVSS 7.7 (HIGH) | RCE
═══════════════════════════════════════════════════════════════════════
[✗] CO KHA NANG BI ANH HUONG - Redis 7.2.5 (can >= 7.2.14)
... (CVE 2-5 tuong tu)
╔══════════════════════════════════════════════════════════════════════╗
║ TOM TAT KET QUA ║
╚══════════════════════════════════════════════════════════════════════╝
[✗] CVE-2026-23479 - VULNERABLE
[✗] CVE-2026-25243 - VULNERABLE
[✗] CVE-2026-25588 - VULNERABLE
[✗] CVE-2026-25589 - VULNERABLE
[✓] CVE-2026-23631 - OK
Ket qua: 1 PASS / 4 VULNERABLE
═══════════════════════════════════════════════════════════════════════
[!] Phat hien 4 CVE. Su dung cac tuy chon --fix-... de khac phuc.
VD: ./script.sh --fix-restore # Chan RESTORE (3 CVE)
VD: ./script.sh --fix-blocking # Chan blocking (1 CVE)
VD: ./script.sh --fix-lua # Chan Lua (1 CVE)
VD: ./script.sh --fix-all # Khac phuc toan bo
═══════════════════════════════════════════════════════════════════════
```
### 修复时的输出结果 (`--fix-restore`)
```
╔══════════════════════════════════════════════════════════════════════╗
║ REDIS CVE SCANNER & MITIGATION TOOL ║
╚══════════════════════════════════════════════════════════════════════╝
[*] THONG TIN REDIS INSTANCE
Host:Port : 127.0.0.1:6379
Version : 7.2.5
...
╔══════════════════════════════════════════════════════════════════════╗
║ FIX NHANH: Chan RESTORE (CVE-2026-25243 + 25588 + 25589) ║
╚══════════════════════════════════════════════════════════════════════╝
Bao ve 3/5 CVE chi voi 1 lenh chan RESTORE
[+] Da backup redis.conf toi: /etc/redis/redis.conf.cve-backup-20260508_120000
[*] Chan RESTORE qua ACL (khong can restart)
=> ACL SETUSER default -restore ... OK
=> ACL SAVE ... OK
[*] rename-command RESTORE "" (can restart)
=> Vo hieu hoa: rename-command RESTORE ""
[!] CAN RESTART REDIS de rename-command co hieu luc
[✓] Da chan RESTORE. Cac CVE duoc bao ve:
+ CVE-2026-25243 (RESTORE double-free/OOB)
+ CVE-2026-25588 (RESTORE + RedisTimeSeries)
+ CVE-2026-25589 (RESTORE + RedisBloom)
```
## 通用修复方法
### 方法 1:ACL (Redis >= 6.0) — 推荐
这是 **最安全、最灵活** 的方法,无需重启 Redis。
```
# 为应用程序创建安全的 ACL 用户
redis-cli ACL SETUSER app_user on >StrongPassword123 ~* \
+@read \ # Quyen doc du lieu
+@write \ # Quyen ghi du lieu
-@dangerous \ # CHAN tat ca lenh nguy hiem (gồm RESTORE)
-@admin \ # CHAN lenh quan tri
-@scripting \ # CHAN Lua scripting
-@blocking \ # CHAN blocking commands
-@keyspace \ # CHAN keyspace notifications
-@pubsub # CHAN pub/sub (neu khong dung)
# 禁用 default user
redis-cli ACL SETUSER default off
# 永久保存 ACL
redis-cli ACL SAVE
```
### 方法 2:rename-command — 需要重启 Redis
将以下行添加到 `redis.conf` 中:
```
# 禁用 RESTORE (CVE-2026-25243, 25588, 25589)
rename-command RESTORE ""
# 禁用 blocking commands (CVE-2026-23479)
rename-command BLPOP ""
rename-command BRPOP ""
rename-command BRPOPLPUSH ""
rename-command BLMOVE ""
rename-command BLMPOP ""
rename-command BZPOPMIN ""
rename-command BZPOPMAX ""
rename-command BZMPOP ""
rename-command XREAD ""
rename-command XREADGROUP ""
# 禁用 Lua commands (CVE-2026-23631)
rename-command EVAL ""
rename-command EVALSHA ""
rename-command SCRIPT ""
rename-command FUNCTION ""
rename-command FCALL ""
rename-command FCALL_RO ""
```
然后重启 Redis:
```
sudo systemctl restart redis-server
# 或者
sudo service redis-server restart
```
### 方法 3:网络配置 + 防火墙
```
# 在 redis.conf 中:
protected-mode yes
bind 127.0.0.1 192.168.1.10 # Chi lang nghe IP tin cay
# iptables — 仅允许内部 IP
iptables -A INPUT -p tcp --dport 6379 -s 127.0.0.1 -j ACCEPT
iptables -A INPUT -p tcp --dport 6379 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 6379 -j DROP
# 保存 iptables
iptables-save > /etc/iptables/rules.v4
```
### 方法 4:以最低权限运行 Redis
```
# 创建无 shell 的 redis 用户
sudo useradd -r -s /bin/false redis
# Chown Redis 目录
sudo chown -R redis:redis /var/lib/redis
sudo chown -R redis:redis /etc/redis
# 以 redis 用户运行 Redis
sudo -u redis redis-server /etc/redis/redis.conf
```
### 方法 5:移除不需要的模块
```
# 检查已加载的模块
redis-cli MODULE LIST
# 移除不必要的模块
redis-cli MODULE UNLOAD timeseries # CVE-2026-25588
redis-cli MODULE UNLOAD bf # CVE-2026-25589
# 从 redis.conf 中删除 loadmodule
# 查找并删除以下行:
# loadmodule /path/to/redistimeseries.so
# loadmodule /path/to/redisbloom.so
```
## 风险评估 — 内部 Redis 系统 / Sentinel
本节适用于在内部网络中运行的 **Redis Sentinel** 或独立 Redis 集群,它们受防火墙(Fortinet、iptables 等)保护,且 **没有直接暴露在互联网上的连接**。
### 总结
| 当前防护级别 | 能否降低风险? | 是否急需升级? |
| ---------------------------------- | ---------------------------------------------------- | ------------------------------------------ |
| 无法访问互联网 | **能** — 阻挡了外部攻击者 | 不急 |
| Fortinet 防火墙 (带有 IPS/DPI) | **能** — 过滤源 IP,IPS 可检测异常 payload | 不急 |
| iptables (限制源 IP) | **能** — 只有允许的 IP 才能连接到 Redis 端口 | 不急 |
| **结合以上 3 种措施** | **被利用的概率极低** | **不急,但应制定升级计划** |
### 核心要点:为什么防火墙是不够的?
这 5 个 CVE 有一个共同点:攻击者必须已经通过 Redis 的 **身份验证**(在 CVSS 向量中为 PR:L — Privileges Required: Low)。防火墙可以拦截未经授权 IP 的连接,但 **无法防御** 以下威胁:
| 威胁 | 发生概率 | 被利用后的后果 |
| -------------------------------------------------------------------------------------------------------- | ---------------------- | ------------------------------------------------------------------ |
| **恶意的内部员工** — 拥有内网访问权限 + 知道 Redis 密码 | 低,但无法排除 | Redis 服务器上的 **RCE**,权限提升,数据窃取 |
| **内部机器被接管 (Lateral Movement)** — 攻击者入侵内网中的任意一台机器,以此为跳板攻击 Redis | 中等 | 所有 Redis 数据被窃取/修改/删除;攻击者可能植入后门 |
| **防火墙配置错误** — 由于错误的规则变更,意外将 Redis 端口开放到外部 | 低 | 相当于直接暴露在互联网上 |
| **供应链 / 第三方** — 合作伙伴、供应商通过 VPN 连接到内网 | 低 | RCE,数据渗出 |
| **防火墙/网络设备自身的漏洞** — 攻击者通过其他漏洞绕过防火墙 | 极低 | 整个内部系统受到影响 |
### 定量风险分析
```
Rủi ro = Xác suất khai thác × Hậu quả
Với firewall + air-gap:
= (RẤT THẤP: 0.5% - 2%/năm) × (NGHIÊM TRỌNG: RCE toàn hệ thống, mất toàn bộ dữ liệu)
= RỦI RO TRUNG BÌNH — vẫn đáng quan tâm
```
### 针对 Sentinel 集群的具体威胁模型
Redis Sentinel 集群还存在特定的风险:
| Sentinel 攻击向量 | 描述 | 相关 CVE |
| ----------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ----------------------------------------------------- |
| **接管 Sentinel** — 攻击者控制 Sentinel 节点,从而故障转移至恶意 replica | Sentinel 通过独立端口(通常为 26379)通信,如果未单独加以保护 | CVE-2026-23631(如果 replica 启用了 `replica-read-only no`) |
| **Replica 提升** — 被接管的 replica 被提升为 master | 整个集群的数据将被篡改 | 所有与 RESTORE 相关的 CVE (25243, 25588, 25589) |
| **Master-replica 同步 (Sync)** — 攻击者拦截同步流量 | 数据在同步过程中被窃取 | CVE-2026-23631 |
### 按优先级排序的建议
| 优先级 | 操作 | 预计耗时 | 是否需要停机? |
| ------------------------------- | --------------------------------------------------------------------------------------------------------- | ------------------- | ------------------------- |
| **P0 — 立即** | 在所有节点(master + replica + sentinel)上运行检查脚本:`./CVE-...sh -H -p -a ` | 2-5 分钟 / 节点 | 否 |
| **P0 — 立即** | 检查所有 replica 上的 `replica-read-only yes`:`redis-cli CONFIG GET replica-read-only` | 1 分钟 / 节点 | 否 |
| **P1 — 本周内** | 通过 ACL 拦截 `RESTORE`(无需重启):`redis-cli ACL SETUSER default -restore; redis-cli ACL SAVE` | 2 分钟 / 节点 | **否** |
| **P1 — 本周内** | 通过 ACL 拦截 `@blocking` 命令 (CVE-2026-23479) | 2 分钟 / 节点 | **否** |
| **P1 — 本周内** | 如果不使用 Lua,通过 ACL 拦截 `@scripting` 命令 (CVE-2026-23631) | 2 分钟 / 节点 | **否** |
| **P2 — 下一个维护窗口** | 在 redis.conf 中添加 `rename-command RESTORE ""`,`rename-command EVAL ""` 等 | 10 分钟(需重启) | **是**(需重启 Redis) |
| **P2 — 下一个维护窗口** | 将 Redis 升级到已修复的版本 (6.2.22, 7.2.14, 7.4.9, 8.2.6, 8.4.3, 8.6.3) | 30-60 分钟 / 集群 | **是**(需重启整个集群) |
### 示例:使用 ACL 保护整个 Sentinel 集群(零停机)
```
# ============================================
# 在每个 Redis 节点上运行 (master + replica)
# ============================================
# 1. 为应用程序创建安全的 ACL 用户
redis-cli -h -p 6379 -a ACL SETUSER app_user on >StrongPass123 ~* \
+@read +@write \
-@dangerous -@admin -@scripting -@blocking \
-restore -debug
# 2. 禁用 default user
redis-cli -h -p 6379 -a ACL SETUSER default off
# 3. 保存 ACL
redis-cli -h -p 6379 -a ACL SAVE
# 4. 复查
redis-cli -h -p 6379 -a --user app_user --pass StrongPass123 PING
```
```
# ============================================
# 在每个 Sentinel 节点上运行 (端口 26379)
# ============================================
# Sentinel 通常不需要 RESTORE/EVAL — 阻止所有危险命令
redis-cli -h -p 26379 -a ACL SETUSER default \
-@dangerous -@admin -@scripting -@blocking -restore
redis-cli -h -p 26379 -a ACL SAVE
```
### 决策流程:是否需要立即升级?
```
Hệ thống Redis của bạn có public-facing không?
├── CÓ → NÂNG CẤP NGAY hoặc áp dụng workaround TRONG 24H
└── KHÔNG (nội bộ / air-gapped)
├── Có dùng Lua scripting (EVAL/EVALSHA)?
│ ├── CÓ → CVE-2026-23631: Kiểm tra replica-read-only, chặn @scripting qua ACL
│ └── KHÔNG → Rủi ro thấp hơn
├── Có dùng RedisTimeSeries hoặc RedisBloom module?
│ ├── CÓ → CVE-2026-25588/25589: Chặn RESTORE qua ACL, nâng cấp module
│ └── KHÔNG → Không bị ảnh hưởng bởi 25588/25589
├── Có dùng blocking commands (BLPOP, XREAD, ...)?
│ ├── CÓ → CVE-2026-23479: Chặn @blocking qua ACL hoặc rename-command
│ └── KHÔNG → Chặn @blocking để an toàn (không ảnh hưởng)
└── KẾT LUẬN:
├── Áp dụng ACL workaround NGAY TRONG TUẦN (không downtime)
└── Lên kế hoạch nâng cấp TRONG MAINTENANCE WINDOW TIẾP THEO
```
### 结论
## ACL 参考
### 重要的命令组
| 组别 | 描述 | 影响的 CVE |
| ------------- | ------------------------------------------------------------------------------------------ | ----------------------------- |
| `@dangerous` | 危险命令(包括 RESTORE, FLUSHDB, FLUSHALL, KEYS, SHUTDOWN, DEBUG, CONFIG) | CVE-2026-25243, 25588, 25589 |
| `@blocking` | 阻塞命令 (BLPOP, BRPOP, BZPOPMIN, XREAD, WAIT, ...) | CVE-2026-23479 |
| `@scripting` | Lua 脚本命令 (EVAL, EVALSHA, SCRIPT, FUNCTION FCALL) | CVE-2026-23631 |
| `@admin` | 管理命令 (CONFIG, ACL, CLIENT, CLUSTER, MONITOR, SHUTDOWN, ...) | 通用防护 |
| `@keyspace` | 与 keyspace 相关的命令 (KEYS, SCAN, FLUSHDB, FLUSHALL, ...) | 通用防护 |
| `@read` | 数据读取命令 (GET, HGET, LRANGE, SMEMBERS, ZRANGE, ...) | 安全 |
| `@write` | 数据写入命令 (SET, HSET, LPUSH, SADD, ZADD, ...) | 安全 |
### 完整的 ACL 配置示例
```
# 1. 创建 admin user (完全权限)
redis-cli ACL SETUSER admin on >AdminPass123 ~* +@all
# 2. 创建 app user (受限权限)
redis-cli ACL SETUSER app on >AppPass123 ~* \
+@read \
+@write \
-@dangerous \
-@admin \
-@scripting \
-@blocking \
-restore \
-debug
# 3. 创建 readonly user (只读)
redis-cli ACL SETUSER reader on >ReaderPass123 ~* \
+@read \
-@dangerous \
-@admin \
-@scripting
# 4. 禁用 default user
redis-cli ACL SETUSER default off
# 5. 保存 ACL
redis-cli ACL SAVE
# 6. 检查 ACL
redis-cli ACL LIST
```
### 检查 ACL 的有效性
```
# 列出所有 ACL 规则
redis-cli ACL LIST
# 检查某个用户的权限
redis-cli ACL GETUSER app
# 检查当前用户
redis-cli ACL WHOAMI
# 查看 ACL 违规日志
redis-cli ACL LOG
```
## 定期检查流程
### 1. 单次检查
```
./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --scan \
-H -p -a \
-o report_$(date +%Y%m%d_%H%M%S).txt
```
### 2. 批量检查多个 Redis 实例
创建文件 `redis_hosts.txt`:
```
# 格式: host:port:password:user
10.0.0.1:6379:pass1:default
10.0.0.2:6379:pass2:default
10.0.0.3:6380:pass3:admin
```
批量检查脚本:
```
#!/bin/bash
# 文件: batch_check.sh
BATCH_RESULT="batch_result_$(date +%Y%m%d_%H%M%S).txt"
while IFS=':' read -r host port pass user; do
[[ "$host" =~ ^#.* ]] && continue # Bo qua comment
[[ -z "$host" ]] && continue # Bo qua dong trong
echo "============================================" | tee -a "$BATCH_RESULT"
echo "Kiem tra: $host:$port" | tee -a "$BATCH_RESULT"
echo "============================================" | tee -a "$BATCH_RESULT"
./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --scan \
-H "$host" -p "${port:-6379}" \
-a "${pass:-}" -u "${user:-default}" \
2>&1 | tee -a "$BATCH_RESULT"
echo "" | tee -a "$BATCH_RESULT"
done < redis_hosts.txt
echo "Bao cao tong hop: $BATCH_RESULT"
```
### 3. 集成到 cron(每日检查)
```
# 添加至 crontab (每天早上 7:00 AM 运行)
0 7 * * * /opt/scripts/CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --scan \
-H 127.0.0.1 -p 6379 -a mypassword \
-o /var/log/redis/cve_report_$(date +\%Y\%m\%d).txt \
> /dev/null 2>&1
```
### 4. 集成到 CI/CD pipeline
```
# GitLab CI 示例
redis-security-scan:
stage: security
image: redis:7-alpine
script:
- chmod +x CVE-2026-25589-25588-25243-23631-23479-REDIS.sh
- ./CVE-2026-25589-25588-25243-23631-23479-REDIS.sh --scan \
-H $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASS \
-o cve_report.txt
artifacts:
paths:
- cve_report.txt
when: always
allow_failure: true
```
## 常见问题解答 (FAQ)
### 问:在应用 `--fix-...` 后,我需要重启 Redis 吗?
**答:** 需要,对于 `rename-command` 的修改——它们仅在重启 Redis 后生效。通过 `CONFIG SET` 进行的修改(例如 `protected-mode`、`replica-read-only`)会立即生效。通过 `ACL SETUSER` + `ACL SAVE` 进行的修改会立即生效,**无需重启**。如果仅使用 ACL(`--fix-restore`、`--fix-blocking`、`--fix-lua`),则不需要重启。脚本会同时应用 ACL(运行时生效)和 rename-command(需重启生效)以提供多层防护。
### 问:拦截 RESTORE 会影响正常运行吗?
**答:** `RESTORE` 命令通常仅在以下情况使用:
- 从备份中恢复数据
- 在实例之间迁移数据
- 自定义数据同步
如果您的应用程序未使用 RESTORE,拦截此命令是安全的。如果确实需要使用,请创建一个具有 RESTORE 权限的专用 ACL 用户,且仅将其用于管理目的。
### 问:我正在使用 Redis < 6.0,ACL 不可用。我该怎么办?
**答:** 对于 Redis < 6.0,您只能使用 `rename-command` 来禁用该命令。步骤如下:
1. 在 redis.conf 中添加 `rename-command RESTORE ""`
2. 为阻塞命令添加 `rename-command`
3. 启用 `protected-mode yes`
4. 设置强密码 `requirepass`
5. 通过防火墙限制连接
6. 重启 Redis
### 问:如何知道是否加载了 RedisTimeSeries/RedisBloom 模块?
**答:** 运行命令:
```
redis-cli MODULE LIST
```
输出将显示当前加载的模块列表及其版本。如果没有看到 `timeseries` 或 `bf`,则说明未加载相关模块。
### 问:`--fix-all` / `--fix-restore` / `--fix-...` 对生产环境安全吗?
**答:** 修复命令执行的都是安全更改:
- 修改前会备份 redis.conf(除非使用 `--no-backup`)
- **ACL** (`-restore`, `-@blocking`, `-@scripting`):立即生效,无停机时间,易于回滚
- **rename-command**:需要重启 Redis 才能生效
- **CONFIG SET**:运行时生效,如果未写入 redis.conf,重启后会丢失
建议:对于生产环境,优先使用 `--fix-restore`、`--fix-blocking`、`--fix-lua`(仅涉及 ACL,无需重启)。然后安排维护窗口以应用带有 `rename-command` 的重启操作。
### 问:如何撤销 (`--fix-...`) 的更改?
**答:**
1. 如果有备份:用备份文件覆盖 redis.conf,然后重启 Redis
2. 如果使用了 `CONFIG SET`:重启 Redis 将从配置文件恢复配置
3. 如果使用了 `ACL SETUSER`:使用 `ACL SETUSER +` 恢复权限
### 问:我应该升级 Redis 吗?
**答:** **如果可以的话,是的。** 升级到已修补的版本是最彻底的解决方案。此脚本适用于以下情况:
- 由于应用程序限制无法立即升级
- 需要时间来测试新版本
- 在等待维护窗口期间需要临时保护措施
### 问:我的 Redis 运行在内网,没有暴露在互联网上,且有防火墙保护——我还需要升级吗?
**答:** **不需要立即升级**,但 **建议应用临时解决方案并制定升级计划**,因为:
- 防火墙仅降低了被攻击的 **概率**,并未完全消除风险
- 内网中的攻击者(恶意员工、被接管的机器、横向移动)仍然可以利用该漏洞
- 如果被利用,后果将是 **全系统的 RCE**——这是最高级别的严重性
- **临时解决方案的成本极低**:添加 ACL `-restore -@blocking -@scripting` 只需 2 分钟,且无停机时间
**建议的路线图:**
1. **本周:** 应用 ACL 临时解决方案(零停机)
2. **下一个维护窗口:** 升级 Redis + 添加 `rename-command`
详情请参阅 [风险评估 — 内部 Redis 系统 / Sentinel](#đánh-giá-rủi-ro--hệ-thống-redis-nội-bộ--sentinel)。
## 参考
- [Redis 官方安全公告](https://redis.io/blog/security-advisory-cve202623479-cve202625243-cve-2026-25588-cve202625589-cve-2026-23631/)
- [GitHub Advisory — CVE-2026-25243 (RESTORE RCE)](https://github.com/redis/redis/security/advisories/GHSA-c8h9-259x-jff4)
- [GitHub Advisory — CVE-2026-23631 (Lua UAF)](https://github.com/redis/redis/security/advisories/GHSA-8ghh-qpmp-7826)
- [Redis ACL 文档](https://redis.io/docs/latest/operate/oss_and_stack/management/security/acl/)
- [Redis rename-command 文档](https://redis.io/docs/latest/operate/oss_and_stack/management/security/#disable-specific-commands)
- [NVD — CVE-2026-25243](https://nvd.nist.gov/vuln/detail/CVE-2026-25243)
- [NVD — CVE-2026-25588](https://nvd.nist.gov/vuln/detail/CVE-2026-25588)
- [OpenCVE — CVE-2026-23479](https://app.opencve.io/cve/CVE-2026-23479)
- [Tenable — CVE-2026-23631](https://www.tenable.com/cve/CVE-2026-23631)
标签:AES-256, CISA项目, CVE修复, DInvoke, RCE, Redis, RedisBloom, RedisTimeSeries, Redis模块, Use-After-Free, Web报告查看器, 内存安全, 安全漏洞, 应用安全, 漏洞评估, 系统运维, 编程工具, 网络安全, 脚本自动化, 远程代码执行, 隐私保护, 高危漏洞