CVE-2026-81934:Redis TLS 待处理数据链表 UAF,先查 tls-port 再按版本线升级
官方公告(2026-08-27 披露,9-01 CVE 记录分数由 9.8 修订为 7.5 High):
https://redis.io/blog/security-advisory-cve-2026-81934/
漏洞位置与触发条件
tlsProcessPendingData()(src/tls.c)在处理 TLS pending-data 链表时存在 use-after-free(CWE-416)。
这段代码只在 Redis 配置了 TLS 支持时才会执行,也就是 tls-port 非 0 的实例。纯明文监听的 Redis 不会进入这条链表,因此不受该漏洞影响。判断是否需要处理,先看配置而不是先看版本。
自查:一条命令
redis-cli CONFIG GET tls-port
返回非 0,且当前二进制是带 TLS 的构建(redis-server --version 里通常能看到 tls 相关构建信息),就落在受影响范围内。没有跑着的实例,直接查配置文件:
grep -nE '^[[:space:]]*tls-port' /etc/redis/redis.conf
同一套部署里若只有部分节点开了 TLS,需要逐节点确认,别拿一个节点的结果代表整个集群。
影响面与公开 PoC
Redis 自评为:需要已认证,加上特定运行时条件,可能以 Redis 进程权限执行任意命令。公开 CVE 记录一度标为 9.8 Critical,后续修订为 7.5 High,评分差异主要来自前置条件(认证 + 时序)。
已有公开 PoC(v12-security),针对官方 amd64 的 Redis 8.8.0 并开启 TLS。做法是:用多个 TLS 客户端 groom pending 链表,借 Lua 超时 / Pub/Sub 事件触发事件循环重入,回收已释放的节点,最终以 Redis 的 uid 执行任意命令。PoC 对时序和堆布局敏感,跑不通不代表目标不可利用,跑得通也不代表线上环境一定能复现同样的堆状态。
修复版本
按当前所在版本线升级,不要为这一个 CVE 跨大版本跳。
Redis Open Source:
- 8.2.9
- 8.4.6
- 8.6.6
- 8.8.2
- 8.10.1
以上属于 2026-08-17 的 SECURITY 批次,包含修复提交 6d088c3。
旧版本线:
- 6.2.24
- 7.2.16
- 7.4.11
Redis Software(企业版):
- 8.2.0-46
- 8.0.20-96
- 7.22.2-179
- 7.8.6-303
修复思路
修复的核心是不再使用预先缓存的迭代器。每一轮处理时先用 tlsPendingRemove() 把节点 detach 出来,再重新 listFirst() 读取下一个节点;在 handler 调用期间不持有 list node 指针。这样即使 handler 内部触发事件循环重入并修改了链表,也不会拿着已经释放的节点继续走。该提交 cherry-pick 自 98ff29b。
如果你的发行版走的是自己维护的补丁集,确认补丁是否等同这两处改动,而不只是版本号对上。
暂时无法升级时的缓解
- 关闭 Redis 的 TLS 支持,或去掉 TLS 监听端口;
- 把 Redis 端口限制为只对可信 IP 开放;
- 启用认证,并使用最小权限 ACL;
- 移除对
CLIENT KILL、Lua 脚本、Pub/Sub 的不必要访问权限。
Redis 本身不应直接暴露在公网。
顺带:CVE-2026-66373
同一批修复里还有 CVE-2026-66373,影响 Redis < 8.8.0,是 RESTORE payload 触发的远程代码执行:同一个 NACK 被多个 consumer 引用,XGROUP DELCONSUMER 删除两个 consumer 时导致 double free。这是 CVE-2026-25243 修复不完整留下的口子。利用需要已认证,并且能执行 RESTORE。
如果你的实例既开了 TLS 又开放了 RESTORE 权限,这一批版本要一起处理。
时间线
厂商公告里的「未见利用」只代表 8-27 当天的状态。PoC 公开后,通常几天内就会出现机会性扫描。补丁窗口按这个节奏排,不要等到厂商确认已被利用再动手。