这洞是真的,9.8 的评分也是 Red Hat 实打实标出来的,但“9.8”不等于“装了 Apache 就默认中招”。真要排查,顺序很简单:先看版本和补丁,再看 mod_http2 到底有没有把 h2 或 h2c 放出来让人摸到。

先对齐几个核心事实:

  • 漏洞本质:Apache HTTP Server 2.4.55 到 2.4.70 里,mod_http2 的 assign_headers() 存在并发同步缺陷,能打成堆破坏,最坏走到未认证 RCE。上游在 2026-11-11 发了 2.4.71 修掉 [S1][S3][S5]。
  • 触发前提:只有实际启用并且可达 h2 或 h2c 的实例受影响,纯跑 HTTP/1.1 根本进不去这段逻辑 [S2][S6][S7]。
  • 修复代码:上游提交 824beab 就改了一行,把 req->headers 换成了 r->headers_in [S8][S9]。
  • 并发形状:不是两个 worker 线程抢同一张 req->headers 表。按 Red Hat 的说法,是 worker 线程通过共享的 lock-free allocator 写进了 connection thread 拥有的内存;CIRCL 那边表述为 worker 可能改到另一个执行上下文分配的 header 表 [S2][S7]。
  • 独立 mod_h2 有坑:Apache 公告把 GitHub 上的 2.0.8 到 2.0.42 全划进了受影响范围,而且没给独立修复版;Wiz 表格的 patched 列写 2.0.42 and newer,正文动作项又写 newer than 2.0.42,自己前后打架。这里以 Apache 公告为准 [S1][S4][S5]。
  • 评分与利用现状:Red Hat 给 9.8(AC:L),cve.org 给 8.1(AC:H),Apache 只写了 critical 没给 CVSS;NVD 页面这轮没读到正文,数字先空着,别把 Red Hat 页面里的 N/A 当成 NVD 评分 [S2][S5]。目前公开 PoC 能稳定复现堆破坏和进程崩溃,没证明 RCE,Wiz 发布时也确认没有可用 exploit 和在野利用 [S3][S4][S5];不过 Red Hat 提了一句,有公开研究演示过对“默认配置启用 mod_http2”服务器的可靠利用(没点名具体研究)[S2][S5]。两边信息放一块看就行,别直接传成“已有在野 RCE”。

一、一行 diff:刚 clone 完副本,转手写回源表

上游修复提交 824beab 非常干脆,1 file changed, +1 -1 [S8]:

c
/* 2.4.70:写回了连接侧共享的源表 */
apr_table_setn(req->headers, "Content-Length", "0");

/* 2.4.71:写本次请求的副本 */
apr_table_setn(r->headers_in, "Content-Length", "0");


看上下文更清楚,2.4.71 的 assign_headers() 开头就已经写了这句 [S9]:

c
r->headers_in = apr_table_clone(r->pool, req->headers);


no_body 分支干的事不复杂:请求没带 Content-Length 但带了 Content-Type,且 eos 已经到了,说明后面不会再有 body,代码就顺手补个 Content-Length: 0 给下游 [S9]。补 0 本身没毛病,问题出在写错表了——前面刚把 req->headers clone 进请求自己的 r->headers_in,后面顺手又写回了连接侧还在共享的 req->headers [S8][S9]。

写代码时顺手写错变量名确实绷不住。顺便解释个容易看岔的点:有人看到 req 是 const h2_request * 会纳闷怎么还能改。C 里的 const 拦的是结构体本身,拦不住结构体成员指针指向的那张 apr_table_t;加上 apr_table_setn 里的 n 只是“不复制 key/value 字符串”,不是只读,它照样改表项、动元数据甚至触发扩容搬数组。对一张连接侧共享的表干这事,就是妥妥的所有权事故。(这两句是从代码和 APR 语义推的,公告里没展开写 [S9]。)

二、触发形状:不是两个 worker 互殴

网上有些转述写成“两个 worker 共用一张 req->headers 表对着写”,这个说法不准。

MERMAID · 图表源代码
sequenceDiagram
    autonumber
    participant C as 客户端
    participant CT as 连接线程
    participant WT as worker线程
    participant AL as 共享分配器
    participant MEM as 连接线程内存
    C->>CT: 单连接并发多条 h2 stream
    CT->>MEM: 持有 connection 侧 header 内存
    C->>WT: stream 交给 worker
    WT->>AL: assign_headers 进入写表分支
    AL->>MEM: 通过共享 allocator 写入
    Note over WT,MEM: 不是两个 worker 共用同一张 req headers 表
    MEM-->>WT: 堆破坏 可能崩溃或被利用

按 Red Hat 和 CIRCL 的描述,本质是 worker 线程跨执行上下文、通过共享的 lock-free allocator 动了连接线程名下的内存 [S2][S7]。

这也解释了为什么它不是“打一发就必炸”:需要并发、时序和堆布局凑到一块 [S2][S5]。9.8 衡量的是网络可达、无需认证、最坏能 RCE 的上限。但 Red Hat 既然明确写了有公开研究在“默认配置启用 mod_http2”的情况下做过可靠利用,就不能当它纯属理论漏洞 [S2]。至于哪些发行版默认开着 HTTP/2,现有来源没给统一清单,老老实实查自己机器的配置。

三、可达性排查:别光盯着版本号看

判断一台机器在不在坑里,看三个条件就行:

  1. 版本在 2.4.55 到 2.4.70 之间,且没打过发行版 backport 补丁 [S1]。
  2. mod_http2 加载了,并且实际启用了 h2 或 h2c [S2][S7]。
  3. 攻击者能把 HTTP/2 请求送进这个 Apache。如果前端 CDN 或反向代理直接把 h2 终结掉,回源只走 HTTP/1.1,后端 Apache 就进不到这段逻辑 [S7]。
MERMAID · 图表源代码
flowchart TD
    A["版本在 2.4.55 到 2.4.70 且未打发行版补丁"] -->|"否"| Z["不在本 CVE 影响范围"]
    A -->|"是"| B{"mod_http2 已加载"}
    B -->|"否"| Z
    B -->|"是"| C{"实际启用并可被对面摸到 h2 或 h2c"}
    C -->|"否"| Y["纯 HTTP/1.1 路径不可达"]
    C -->|"是"| D{"前端 CDN 或反向代理终止 h2 且回源 HTTP/1.1"}
    D -->|"是"| Y
    D -->|"否"| X["可达 按暴露面处置"]

CIRCL 给的对照表也支持这个判断:没加载模块安全,加载了但只跑 HTTP/1.1 安全,开了 h2 或 h2c 危险,只在某个 vhost 里开了那条路径就可能被打到 [S7]。

查配置有个常见盲区:只 grep 主配置。Apache 核心默认是 Protocols http/1.1 [S10],光加载 mod_http2 不会自动开启 h2;但任何单个 vhost 都可以单独写 Protocols 把全局配置盖掉 [S7]。所以 apachectl -S 和全量目录 grep Protocols 得一起跑。

另外别忽略内网机器。只要不可信网络能摸到、且协商出了 h2 的内部反代或设备管理口,一样在风险面里 [S5]。至于 Wiz 报告里写的“64% 云环境有受影响版本、51% 有公网暴露”,它自己也注明了没把配置算进去,当个背景数字看看就行,不能直接等价于可利用面 [S3][S4]。

四、RHEL 差异与独立 mod_h2 的版本坑

  • RHEL 系列:RHEL 8 及更早版本带的 mod_http2 低于 2.0.8,没有这段代码,不受影响 [S2][S6][S7]。RHEL 9 和 10 受影响,但因为每个 HTTP/2 stream 用了单独的 allocator,Red Hat 认为利用难度高,评级降到了 Important,并在 11-11 放出了修复包 [S2][S6][S7]。
  • 发行版版本号:老生常谈了,厂商经常 backport 修复但不改上游版本号,别光看 httpd -v 吐出来的字符串下结论,去核对发行版的 advisory 和实际包版本 [S6][S7]。
  • **独立 mod_h2**:Apache 公告直接把 GitHub 上 2.0.8 到 2.0.42 全列成受影响,而且没给独立模块的新版号 [S1][S5][S6]。Wiz 表格里写了个 2.0.42 and newer 明显跟自己正文写的 newer than 2.0.42 冲突,千万别把 2.0.42 当安全版本 [S4]。用独立模块的,稳妥做法是直接迁到带修复的 Apache HTTP Server 包,或者按 vendor 指示处理 [S5]。

五、评分与 CWE 口径分歧

ECHARTS · 图表源代码
{"title":{"text":"CVE-2026-119618 评分对比"},"tooltip":{"trigger":"axis"},"xAxis":{"type":"category","data":["Red Hat","cve.org"]},"yAxis":{"type":"value","min":0,"max":10,"name":"CVSS v3.1"},"series":[{"name":"Base Score","type":"bar","data":[9.8,8.1],"label":{"show":true,"position":"top"}}]}

Red Hat 给了 9.8(AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H),cve.org 给了 8.1,核心分歧就在攻击复杂度(AC:L vs AC:H)[S2]。CWE 分类也不统一,Red Hat 标成 CWE-20,CIRCL 和 Horizon3 标成 CWE-362 [S2][S5][S7]。这些属于各家打分和归类的口径差异,不影响一线排查动作。

六、直接上手的排查与处置命令

1. 查本机加载与 Protocols 配置

bash
apachectl -v
apachectl -M | grep -i http2
apachectl -S
grep -RniE '^[[:space:]]*Protocols[[:space:]]+' /etc/apache2 /etc/httpd 2>/dev/null


Debian/Ubuntu 看 /etc/apache2,RHEL/CentOS 看 /etc/httpd,有自定义路径自己加上,重点盯每个 vhost 里有没有覆盖 Protocols [S7]。

2. 实测协议协商(尽量直连 Apache)

bash
HOST='your.apache.host'
SCHEME='https'
curl --noproxy '*' --http2 -sS -o /dev/null -w 'HTTP/%{http_version}\n' "$SCHEME://$HOST/"

SCHEME='http'
curl --noproxy '*' --http2-prior-knowledge -sS -o /dev/null -w 'HTTP/%{http_version}\n' "$SCHEME://$HOST/"


第一条测 TLS ALPN 的 h2,第二条测明文 h2c [S7]。注意加 --noproxy '*' 且尽量绕开前置 CDN 直连源站测试。返回 HTTP/2 说明这层端点接了 h2,但不代表打到后面一定通;返回 HTTP/1.1 也不代表其他监听端口或 vhost 就一定没开 [S7]。

3. 升级与临时止血

  • 能升就升:Apache HTTP Server 升到 2.4.71 及以上,发行版按官方 errata 打补丁 [S1][S6][S7]。
  • 暂不能升(兜底):在全局和所有 vhost 里显式写死 Protocols http/1.1,apachectl -t 过一遍配置然后 reload/restart;确认业务不依赖 mod_http2 的直接把模块卸载掉 [S4][S7]。如果前面有反代或 CDN,确认回源走的是 HTTP/1.1 [S7]。记住关 h2 只是缩小暴露面,不是打补丁 [S5][S7]。

4. 升完后的收尾核对

  • 重启后确认跑在内存里的全是新版本进程,没有老 worker 进程挂着没退 [S6][S7]。
  • 顺手翻一眼日志和进程树:有没有异常崩溃、重启、内存破坏报错;有没有 httpd -> sh、apache2 -> bash、httpd -> curl/wget 这类离谱的子进程;web 根目录和 /tmp 有没有莫名其妙的新文件或异常外连 [S6][S7]。这些是排查线索,不算实锤 IOC,但按照这种洞的公开节奏,扫描探测很快就会铺开,提前看一眼不亏 [S7]。

七、时间线复盘

MERMAID · 图表源代码
timeline
    title CVE-2026-119618 时间线
    2026-10-26 : Anthropic OSS Scanner 报告漏洞
    2026-11-03 : Google Cloud Vulnerability Research 独立报告
    2026-11-11 : Apache 发布 2.4.71 与 CVE 记录
    2026-11-12 : 第三方 sanitizer PoC 复现堆破坏


参考资料