文章总结: Redis发布紧急预警CVE-2026-23479补丁遗漏导致UAF漏洞,攻击者利用阻塞命令触发客户端驱逐实现RCE,影响多版本需立即升级至安全版本并开启认证限制访问。 综合评分: 95 文章分类: 漏洞预警,漏洞分析,应急响应,安全建设,数据安全
紧急预警|Redis blocked-client CVE-2026-23479 远程代码执行漏洞
撅人
2026年8月20日 00:00 广东
在小说阅读器读本章
去阅读
🔴 导语 · 紧急预警 · PoC 已公开 · 释放后使用 → RCE
用 Redis 的、缓存中间件运维、DBA 和安全兄弟请注意!⚠️
一条阻塞命令 + 一次客户端驱逐,就能让你的 Redis 服务器弹 shell。 攻击者利用 BLPOP/XREAD 等阻塞命令创建 blocked client,在命令重执行过程中触发客户端内存驱逐,链表迭代器引用到已释放的节点——释放后使用(UAF),已回收的内存被当作客户端结构使用,最终实现任意代码执行。
更让人头疼的是,这是 CVE-2026-23479 的”补丁遗漏”。今年 5 月 Redis 修过一轮 blocked-client UAF(CVE-2026-23479),但修复只覆盖了 unblockClientOnKey() 路径,漏掉了同在 blocked.c 里的 handleClientsBlockedOnKey()——同一个代码路径里的另一条 UAF 利用链。PoC 已在 GitHub 公开,今天(8 月 19 日)刚披露。
对于默认无认证配置的 Redis 实例(公网裸奔的那些),不需要任何权限,直接打。
🔍 漏洞速览
| | | | — | — | | 漏洞编号 | 暂无 CVE (关联 CVE-2026-23479 · PR #15594) | | 漏洞类型 | 释放后使用 UAF(CWE-416)→ 远程代码执行 | | 影响产品 | Redis 7.2.0+ 全分支 | | 攻击前提 | 普通权限(默认无认证实例无需权限) | | 攻击方式 | 阻塞命令 → 命令重执行触发驱逐 → 迭代器引用已释放节点 → UAF → RCE | | 受影响版本 | 7.2.0 – 7.2.15 / 7.4.0 – 7.4.10 / 8.2.0 – 8.2.8 / 8.4.0 – 8.4.5 / 8.6.0 – 8.6.5 / 8.8.0 – 8.8.1 / 8.10.0 | | 安全版本 | 8.8.2 / 8.10.1 / 8.6.6 / 8.4.6 / 8.2.9 / 7.4.11 / 7.2.16 | | PoC 情况 | 已公开 (GitHub PoC 仓库) | | 补丁状态 | 官方补丁已发布(8 月 19 日) | | 披露时间 | 2026-08-19 |
💥 核心危害:Redis 一穿,谁遭殃?
Redis 在企业里的角色不用多说——缓存、消息队列、分布式锁、会话存储、排行榜。 它一穿,连锁反应是这样的:
🔓 无认证实例直接沦陷:大量 Redis 实例默认不开启认证(bind 0.0.0.0 + 无 requirepass),Shodan/FOFA 上一搜几十万个。攻击者不需要任何凭据,直接连上去发阻塞命令就行
⚡ UAF 直通 RCE:释放后使用漏洞不是简单的信息泄露——攻击者通过堆风水控制已释放内存的复用,把伪造的客户端结构体塞进迭代器路径,最终劫持控制流执行任意代码,服务器当场失陷
🔑 缓存数据全量泄露:Redis 里存的是会话 token、用户信息、业务缓存、API 密钥——服务器被打穿后这些数据全部可被读取和导出
🌐 内网横向跳板:Redis 服务器通常部署在内网核心区,拿到 RCE 后可作为跳板进一步横向渗透数据库、消息队列、应用服务器
🔁 补丁遗漏的教训:今年 5 月 CVE-2026-23479 修过一轮 blocked-client UAF,但只修了 unblockClientOnKey(),漏掉了同文件里的 handleClientsBlockedOnKey()。你以为修了的,它换条路又来了。
💬 攻击者成本 ≈ 几条 Redis 命令(BLPOP/XREAD)+ 触发客户端驱逐。防御方成本 ≈ Redis 服务器失陷 + 缓存数据泄露 + 内网被横向 + 紧急升级。 对于公网无认证的 Redis,这几乎等于”直接送”。
🧠 漏洞原理(人话版)
先搞清楚几个概念
阻塞客户端(Blocked Client):当客户端执行 BLPOP、BRPOP、XREAD BLOCK 等阻塞命令时,如果目标 key 不存在或没有数据,Redis 不会返回错误,而是把客户端标记为”阻塞”状态(CLIENT_BLOCKED),挂起等待。当其他客户端向这个 key 写入数据时,Redis 会唤醒所有阻塞在这个 key 上的客户端,让它们重新执行命令。
阻塞等待列表:每个 key 上所有阻塞等待的客户端,被组织成一个链表(linked list)。Redis 用 listIter 迭代器遍历这个链表,逐个唤醒并重执行命令。
客户端驱逐(Client Eviction):当 Redis 的客户端总内存超过配置阈值(maxmemory-clients)时,Redis 会主动断开占用内存最大的客户端,释放其 client 结构体和链表节点。
漏洞本质:迭代器在遍历过程中,被遍历的链表节点被释放了
问题出在 handleClientsBlockedOnKey() 函数里。原始代码长这样:
// 漏洞代码:迭代器在循环外创建,遍历过程中链表可能被修改
listIter li;
listRewind(clients, &li); // 创建迭代器
long count = listLength(clients);
while ((ln = listNext(&li)) && count–) {
// 处理当前阻塞客户端,重执行其命令
// ⚠️ 重执行过程中可能触发客户端驱逐
// ⚠️ 同一链表中的其他阻塞客户端被释放
// ⚠️ 迭代器 li 仍指向已释放的节点 → UAF
}
问题就一句话:迭代器在循环外创建,循环内链表节点被释放了,迭代器还在用。
攻击流程 4 步走
🚨 攻击流程
第 1 步:创建多个阻塞客户端
攻击者通过多个连接执行 BLPOP/XREAD BLOCK 等阻塞命令,在同一个 key 上创建多个阻塞客户端。这些客户端被组织在同一个链表里等待唤醒。其中一个客户端故意设置很大的输出缓冲区,使其成为客户端驱逐的首选目标。
第 2 步:触发 key 就绪 + 命令重执行
攻击者通过另一个连接向目标 key 写入数据(如 XADD/LPUSH),Redis 检测到 key 就绪,调用 handleClientsBlockedOnKey() 遍历阻塞客户端链表,逐个唤醒并重执行它们的命令。
第 3 步:命令重执行触发客户端驱逐
在处理某个阻塞客户端、重执行其命令的过程中,Redis 检测到客户端总内存超过 maxmemory-clients 阈值,触发客户端驱逐。那个缓冲区很大的阻塞客户端被选中驱逐——它的 client 结构体和链表节点被释放。但迭代器还指向这个已释放的节点。
第 4 步:UAF → 堆风水 → RCE
迭代器继续遍历,读取已释放的内存。攻击者通过堆风水(heap spraying/grooming)控制这块被释放内存的复用——把伪造的 client 结构体塞进去。迭代器把这块内存当作合法的 client 结构体使用,其中被篡改的函数指针或 GOT 表项被调用,控制流被劫持,执行任意代码。
⚠️ 和 CVE-2026-23479 的关系
CVE-2026-23479(2026 年 5 月披露)是同一个文件 blocked.c 里的另一个 UAF:
• CVE-2026-23479 出在 unblockClientOnKey() —— 命令重执行返回 C_ERR 后没检查 client 是否已释放
• 本次漏洞出在 handleClientsBlockedOnKey() —— 链表迭代器在驱逐后引用已释放节点
两个漏洞在同一个代码路径上,只是触发位置不同。5 月修了一个,8 月发现漏了另一个。
🔍 修复补丁长什么样?
修复思路很清晰——不用迭代器了,每次迭代都重新查找链表:
// 修复后:去掉 listIter,每次循环重新查找链表
long count = listLength(clients);
while (count– > 0) {
/* 每次都重新查找,因为上一次处理可能已经
* 释放了整个链表 */
de = dictFind(rl->db->blocking_keys, rl->key);
if (!de) break;
list *clients = dictGetVal(de);
listNode *ln = listFirst(clients);
// 把当前客户端移到链表尾部,保证处理顺序
listRotateHeadToTail(clients);
client *receiver = listNodeValue(ln);
// 处理 receiver…
}
核心改动:删掉 listIter,用 dictFind() 在每次循环中重新查找阻塞客户端列表——如果链表在上一次处理中被释放了,dictFind() 返回 NULL,循环安全退出。不再持有任何可能过期的引用。
⏱️ 3 秒自查
❌ 受影响版本(红区)
• 7.2.0 – 7.2.15 / 7.4.0 – 7.4.10
• 8.2.0 – 8.2.8 / 8.4.0 – 8.4.5
• 8.6.0 – 8.6.5 / 8.8.0 – 8.8.1 / 8.10.0
• 低于 7.2.0 的版本不受此漏洞影响
✅ 安全版本(绿区)
• 主线:8.8.2(推荐)
• 其他分支:8.10.1 / 8.6.6 / 8.4.6 / 8.2.9 / 7.4.11 / 7.2.16
自查命令:
1. 查 Redis 版本
redis-cli INFO server | grep redis_version
Docker 部署看镜像 tag:
docker inspect redis –format ‘{{.Config.Image}}’
2. 检查是否开启了认证(关键!)
redis-cli CONFIG GET requirepass
返回空 → 🔴 高危!无认证,任何人都能连
返回密码 → 🟡 有认证,但仍可被有凭据的攻击者利用
3. 检查是否暴露在公网
redis-cli CONFIG GET bind
返回 0.0.0.0 → 🔴 高危!公网可访问
返回 127.0.0.1 → 🟢 仅本地访问
4. 检查是否有异常的阻塞客户端
redis-cli INFO clients | grep blocked_clients
blocked_clients 数量异常高 → 可能有攻击者在构造利用场景
正常业务也会用阻塞命令,需对比日常基线
5. 查客户端列表,看有没有可疑连接
redis-cli CLIENT LIST
重点看:异常 IP、大量阻塞连接、超大输出缓冲区
6. 检查 Redis 日志有没有异常崩溃或 OOM 记录
grep -E “crash|SIGSEGV|oom|evict” /var/log/redis/redis.log
有 SIGSEGV 段错误 → 可能已被 UAF 攻击触发过
Redis 正常运行不会崩溃,崩溃即异常
🛡️ 修复方案
✅ 方案一:升级版本(推荐,根治)
补丁已于 8 月 19 日发布,根据当前版本分支选择对应安全版本:
| | | | — | — | | 当前版本 | 升级目标 | | 8.10.x | 8.10.1 | | 8.8.x | 8.8.2 (主线推荐) | | 8.6.x | 8.6.6 | | 8.4.x | 8.4.6 | | 8.2.x | 8.2.9 | | 7.4.x | 7.4.11 | | 7.2.x | 7.2.16 | | 低于 7.2.0 | 不受影响,但建议升级到 8.8.2 |
源码编译升级
wget https://github.com/redis/redis/archive/refs/tags/8.8.2.tar.gz
tar xzf 8.8.2.tar.gz && cd redis-8.8.2
make && make install
Docker 升级
docker pull redis:8.8.2
docker stop redis && docker rm redis
docker run -d –name redis -p 6379:6379 -v redis-data:/data redis:8.8.2 redis-server –requirepass “你的强密码”
包管理器升级(Ubuntu/Debian)
apt update && apt install redis-server
注意:发行版仓库的版本可能落后,确认版本号
官方发布说明:github.com/redis/redis/releases/tag/8.8.2
⚠️ 方案二:临时缓解——网络收口 + 认证(立刻执行)
如果暂时无法升级,必须立刻掐断攻击面:
1. 安全组/防火墙:只允许可信来源访问 Redis 端口
iptables -A INPUT -p tcp –dport 6379 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp –dport 6379 -j DROP
2. 立即开启认证(如果还没有)
redis-cli CONFIG SET requirepass “你的强密码”
同时修改 redis.conf 永久生效
3. 限制 bind 地址,不要绑定 0.0.0.0
redis-cli CONFIG SET bind 127.0.0.1 10.0.0.5
4. 禁用/重命名危险命令
redis-cli CONFIG SET rename-command CONFIG “”
redis-cli CONFIG SET rename-command EVAL “”
⚠️ 认证和网段收口只能降低被远程利用的风险——如果攻击者已有 Redis 凭据(如内部人员、泄露的密码),仍然可利用此漏洞。升级才是正道。
🛡️ 方案三:降低客户端驱逐触发概率
这个漏洞的触发条件之一是客户端驱逐——提高 maxmemory-clients 阈值或关闭客户端驱逐可以降低触发概率,但不能根治:
提高 maxmemory-clients 阈值(或设为 0 关闭驱逐)
redis-cli CONFIG SET maxmemory-clients 2gb
设置合理的客户端输出缓冲区限制
redis-cli CONFIG SET client-output-buffer-limit “normal 0 0 0 replica 256mb 64mb 60 pubsub 32mb 8mb 60”
💡 关闭客户端驱逐后 Redis 不会主动断开大内存客户端,但这只是降低触发概率——攻击者仍可能通过其他方式触发内存释放。升级才是根治。
🕵️ 入侵排查清单
UAF 漏洞利用后可能不留下明显的命令痕迹,但你要排查:
☐ 查 Redis 日志有没有 SIGSEGV 段错误或异常崩溃记录(UAF 触发的典型现象)
☐ 查有没有异常的客户端连接(未知 IP、大量短连接、阻塞命令频繁出现)
☐ 查 blocked_clients 统计有没有异常飙升
☐ 查 Redis 服务器有没有异常的子进程、定时任务或新增文件(RCE 后的持久化手段)
☐ 查 Redis 服务器有没有异常网络外连(反弹 shell、数据外传)
☐ 查 Redis 持久化文件(dump.rdb / appendonly.aof)有没有被篡改
☐ 查有没有未知的 Redis 用户或 ACL 变更
☐ 如果 Redis 无认证且暴露在公网——假设已被攻陷,全盘排查
☐ 检查同网段的其他服务是否有被横向渗透的痕迹
⚠️ 安全提醒
这个漏洞最让人头疼的地方不是它有多复杂——它是 CVE-2026-23479 的”老地方补漏没补干净”。
今年 5 月,Redis 修了 unblockClientOnKey() 里的 UAF(CVE-2026-23479),但同一个 blocked.c 文件里、同一个阻塞客户端处理路径上的 handleClientsBlockedOnKey() 也有同样的问题——链表迭代器在驱逐后引用已释放节点。修了一个,漏了另一个,PoC 已公开。
UAF 漏洞的利用门槛比 SQL 注入高——需要堆风水控制内存复用——但 PoC 已经公开了。而且 Redis 的攻击面比一般应用大得多:大量 Redis 实例默认无认证 + 绑定 0.0.0.0 + 暴露在公网。Shodan 上一搜几十万个。对于这些实例,攻击者不需要任何凭据,直接连上去就能利用。
修复补丁本身很干净——去掉迭代器,每次循环重新查找链表。思路简单但有效:不持有任何可能过期的引用,就不可能有 UAF。 这也是给所有 C 开发者的教训:如果你的链表/树在遍历过程中可能被修改(节点被删除/释放),就不能用固定迭代器——要么每次重新查找,要么用引用计数/标记删除。
如果你家的 Redis 还跑在公网上且没开认证,今晚就去升级、加密码、改 bind。别等服务器被打穿了才想起来。
转发给缓存运维、DBA、安全兄弟,特别是还有 Redis 6.x 甚至更老版本在跑的团队——该升级了。
📎 官方参考
• 修复 PR:github.com/redis/redis/pull/15594
• Redis 8.8.2 发布说明:github.com/redis/redis/releases/tag/8.8.2
• Redis 安全公告:redis.io/blog/security-advisory…
• CVE-2026-23479 NVD:nvd.nist.gov/vuln/detail/CVE-2026-23479
• 腾讯云安全公告:cloud.tencent.com/announce/detail/2441
本文仅供安全研究与防御参考,修复请以 Redis 官方公告为准。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:撅人 《紧急预警|Redis blocked-client CVE-2026-23479 远程代码执行漏洞》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。











评论