此前以 CVE Replay 为名发布。仓库名称和呈现方式已更改;固定版本、原始报告者署名、fixture 路径和记录结果保留其原始身份。
独立的离线研究使用精确版本和有界 fixture 比较已发布的修复。每项研究都明确保留其测量行为、传输边界和署名。
CVE-2026-44431 · urllib3 2.6.3 → 2.7.0 · 复现于 2026 年 9 月 27 日
一个请求携带三个敏感头发往一个源。重定向改变了目的地。下一个请求是否仍然携带它们?
这个独立回归测试运行来自两个精确 urllib3 版本的真实重定向实现。版本 2.6.3 在受影响的低层 API 中保留全部三个头。版本 2.7.0 移除它们。一个无害头得以保留,普通请求仍然正常工作。
| Fixture | urllib3 2.6.3 | urllib3 2.7.0 |
|---|---|---|
| 低层跨源重定向 | 保留 3 个敏感头 | 保留 0 个 |
| 使用小写名称的同一用例 | 保留 3 个 | 保留 0 个 |
| 高层 API 对照 | 保留 0 个 | 保留 0 个 |
| 直接 200 响应 | 按预期保留 3 个 | 按预期保留 3 个 |
| 显式禁用重定向 | 一次调用;返回 302 | 一次调用;返回 302 |
| 自定义移除集添加无害标记 | 保留全部 4 个头 | 移除全部 4 个 |
12/12 场景预期通过。 每个场景还检查响应状态、传输调用次数、初始头集合、无害头结果,以及调用方的头未被修改。易受攻击的结果是预期的基线结果,而非通过的安全检查。
机器可读结果 包含捕获的参数、精确 wheel 哈希、运行时、测试源哈希、署名和复现时间。
上游公告 发布于 2026 年 5 月 7 日,指出 urllib3 的代理低层重定向路径中存在信息暴露问题。它将版本 >=1.23, <2.7.0 列为受影响。调用 ProxyManager.connection_from_url(...).urlopen(..., assert_same_host=False) 可能将配置的敏感头带入到另一源的重定向请求中。高层管理器 API 已经移除了它们。
上游修复 在递归低层请求之前应用 Retry.remove_headers_on_redirect。我们的小写头用例遵循上游回归测试对头名称大小写的关注。自定义移除用例检查该规则是否遵循配置的集合,而不仅仅是三个默认名称。
公告将 christos-cantina-security 列为报告者,illia-v 列为协调者,sethmlarson 列为修复审查者。Sergio Rodriguez 在此的贡献是独立的离线测试框架和前后分析。这是对他们已发布 CVE 的复现。
使用 Python 3.10 或更高版本。无需 pip install 或虚拟环境:每个版本都从其在全新隔离子进程中的纯 Python wheel 直接导入。
从 portfolio 仓库根目录:
python -B ./labs/cve-replay/run_replay.py --fetch
python -B ./labs/cve-replay/run_replay.py
第一条命令将两个精确 wheel 下载到实验室被忽略的 .cache/wheels/ 目录,并根据清单检查其 SHA-256 哈希。第二条命令使用该缓存而不下载。对于独立源代码检出,运行 python -B run_replay.py --fetch,然后运行不带 --fetch 的同一命令。--cache 接受不同的本地缓存目录。
HTTPConnectionPool._make_request 被替换为双响应传输:一个带有固定 location 的 302,然后是一个 200。fixture 捕获到达该边界的参数。urllib3 的解析、重试策略、头过滤和递归重定向处理从所选 wheel 原样执行。
所有目的地都是固定的保留 .invalid 名称;所有头值都以 DUMMY 开头。套接字构造和 DNS 函数立即抛出异常。库的导入时 IPv6 能力探测被拒绝并单独记录;重放场景不尝试任何网络操作。没有监听服务器或实时目标。
这验证了重定向参数处理。它不测量端到端代理流量。版本 2.7.0 是针对此特定 CVE 的第一个修复;此历史比较并非建议选择它而非更新的受支持版本。
fixture 脚本和分析是原创 portfolio 作品。urllib3 是一个上游项目,根据其 MIT 许可证 分发;其代码和发布 wheel 未在 portfolio 源代码归档中重新分发。它们从 PyPI 单独下载,并为实验原样导入。