Announcement

👇Official Account👇

Welcome to join the group & private message

Article first/tail QR code

Skip to content

Redis CVE-2026-81934 深度分析:TLS 握手中的 Use-After-Free 与未认证 RCE

2026 年 9 月初,Redis 修复了一个影响 8.8.0 版本的释放后重用(Use-After-Free, CWE-416)漏洞,编号 CVE-2026-81934,CVSS 7.5。漏洞位于 tlsProcessPendingData() 函数,允许远程未认证攻击者通过精心构造的 TLS 数据流,以 Redis 服务器进程权限执行任意命令。官方补丁已合入(commit 6d088c3),且已有公开 PoC 流出。

Redis 是互联网里暴露面最广的基础组件之一,"未认证 + 远程 + RCE"三个条件叠加,值得每一个后端工程师认真看一遍。

一、漏洞位置:TLS 事件循环中的生命周期错位

Redis 的 TLS 支持基于 OpenSSL。当 Redis 以 TLS 模式运行时,事件循环会调用 tlsProcessPendingData() 处理 TLS 层缓存的待处理数据:

text
┌─────────────────────────────────────────────────────┐
│        Redis 事件循环(TLS 模式,简化)                │
├─────────────────────────────────────────────────────┤
│  1. epoll_wait() 返回 → 某 client fd 可读            │
│  2. readQueryFromClient(fd)                         │
│       └─ SSL_read() 读取 TLS 记录                    │
│  3. tlsProcessPendingData()                         │
│       └─ 处理 OpenSSL 内部缓冲中残留的 TLS 握手数据    │
│  4. 处理结果可能触发 client 对象的释放(认证失败/       │
│     协议错误/连接关闭路径)                            │
│  5. ★ 但调用链上层的指针仍指向已释放的 client        │
│     → 后续写入/访问 = Use-After-Free                 │
└─────────────────────────────────────────────────────┘

问题本质是经典的所有权歧义client 对象可能被事件循环的多个阶段引用——连接处理器持有它,TLS 处理函数持有它,认证回调也持有它。当某条路径(例如握手期间收到非法记录、触发连接终止)在函数内部释放了 client,而外层调用者并不知情、继续使用同一个指针时,就构成了 UAF。

攻击者的利用窗口正是"释放之后、外层继续使用之前"的间隙。通过在释放后立刻建立新连接并喷射受控数据,可以让堆分配器把新数据放到刚释放的 client 对象的位置,外层的"继续使用"就变成了对攻击者控制数据的读写,进而劫持虚表/函数指针完成 RCE。

二、UAF 是怎么变成 RCE 的:堆风水一分钟

给不熟悉二进制漏洞的读者快速补一下这个链条:

text
释放 client 结构 (大小 ~0x100-0x200 字节)


攻击者快速建立 N 个新 TLS 连接
        │  每个连接的握手数据被分配进刚释放的槽位

client 槽位现在装着攻击者可控的字节


外层代码继续调用 client->reply 回调 / 遍历 client 链表
        │  实际执行的是攻击者数据中的函数指针

任意代码执行(以 redis-server 进程权限)

Redis 进程通常以 redis 用户运行,但拿到进程权限后,攻击者的第一步往往是读取 dump.rdb、AOF 中的业务数据,或利用 Redis 常见的高权限部署(容器内 root、挂载宿主机 SSH 目录)进一步横向移动。2019 年的 Redis 未授权 RCE(写 crontab / SSH key)浪潮就是前车之鉴。

三、影响范围与自查

影响版本:Redis 8.8.0(官方公告口径);启用 TLS 的部署才是暴露面——redis.confport 0tls-port 未配置的实例不受此路径影响。

快速自查脚本(检查版本与 TLS 暴露状态):

bash
#!/usr/bin/env bash
# check-redis-cve-2026-81934.sh —— 只读检测,无副作用
REDIS_CLI=${REDIS_CLI:-redis-cli}

echo "== 1. 版本检查 =="
VER=$($REDIS_CLI INFO server 2>/dev/null | grep redis_version | cut -d: -f2 | tr -d '\r')
echo "redis_version: ${VER:-unknown (可能需要认证或未运行)}"

echo "== 2. TLS 暴露检查 =="
TLS_PORT=$($REDIS_CLI CONFIG GET tls-port 2>/dev/null | tail -1)
PORT=$($REDIS_CLI CONFIG GET port 2>/dev/null | tail -1)
echo "plain port : ${PORT:-unknown}"
echo "tls port   : ${TLS_PORT:-unknown}"

echo "== 3. 结论 =="
if [ "$TLS_PORT" != "0" ] && [ -n "$TLS_PORT" ]; then
  case "$VER" in
    8.8.0) echo "[!] 高风险:TLS 已启用且版本受影响,请立即升级 ≥8.8.1/官方修复版" ;;
    8.8.*) echo "[?] 子版本请对照官方公告确认是否已包含 commit 6d088c3" ;;
    *)     echo "[i] 版本不在受影响列表,但建议保持升级" ;;
  esac
else
  echo "[i] TLS 未启用,本次漏洞的远程触发路径不适用"
fi

网络侧排查:ss -tlnp | grep 6379 确认 Redis 是否直接暴露公网。官方与社区的一贯建议仍然有效——Redis 永远不要直接暴露公网,置于内网 + ACL + TLS 双重保护之后。

四、修复与加固

升级是唯一正解。官方修复 commit:redis/redis@6d088c335d5c3ec49a6c28486140b498e70b7834,升级到包含该 commit 的发行版本即可。无法立即升级时,缓解措施按优先级:

  1. 临时关闭 TLS 对外暴露:改走内网明文 + mTLS 网关(如 stunnel/envoy 终结 TLS),把易受攻击的 Redis 内置 TLS 路径从公网摘掉;
  2. 强制 ACL + requirepass:即使 RCE 路径被触发前置条件不满足,也未认证 RCE 的"未认证"前提消失大半;
  3. 容器部署加固:以非 root 运行、只读根文件系统、--cap-drop=ALL、seccomp 限制 execve,把 RCE 的后利用难度抬高;
  4. WAF/IDS 规则:对 6379 端口的 TLS 握手流量异常(同一 IP 高频新建连接、超短握手即断开)告警——这正是堆喷射的特征。

五、给开发者的两点工程启示

第一,事件驱动架构里的对象所有权要显式化。 这个漏洞的模式在 C/C++ 网络程序里极其常见:一个对象被事件循环的多个回调持有,释放发生在"看不见的地方"。工程上的解法包括引用计数(如 libuv 的 handle close 语义)、代际指针(generation counter,释放后指针失效检查)、以及把"是否已释放"作为状态机的显式状态。Go/Java 开发者虽然被 GC 保护,但同样的逻辑错误会表现为数据竞争或泄漏——审查并发代码时,"这个对象归谁管"永远值得问一遍。

第二,补丁响应速度要按暴露面分级。 这次 Redis 漏洞从补丁发布到公开 PoC 只有数天。对直接暴露公网的关键组件(Redis、数据库、消息队列),建议把"高危 CVE → 24 小时内完成评估、72 小时内完成升级"写进运维 SLA;对纯内网组件可以放宽,但要有清单知道哪些实例受影响——不知道自己跑了什么版本,是最贵的故障。

参考资料

  • Redis 官方修复 commit:github.com/redis/redis/commit/6d088c335d5c3ec49a6c28486140b498e70b7834
  • The Hacker Wire: "Redis Use-After-Free RCE in TLS Handling (CVE-2026-81934)"
  • CN-SEC 漏洞斥候 20260902 期
  • CWE-416: Use After Free
  • Redis 官方安全指南:redis.io/docs/management/security

本文同步发布于 friday-go.icu,欢迎交流你的 Redis 安全实践。

上次更新于: