libcurl HTTP方法处理中的越界读取漏洞分析与修复

本文详细分析了一个在libcurl核心HTTP处理中发现的内存安全漏洞。该漏洞源于未正确终止的字符串,导致在处理HTTP方法和检测CONNECT请求时可能发生越界读取,从而引发未定义行为、程序崩溃或逻辑错误。

报告 #3434510 - HTTP方法处理中的越界读取导致未定义行为和潜在崩溃

摘要

  • 组件:libcurl 核心 HTTP 处理(HTTP/2请求翻译和CONNECT检测)
  • 类型:由于缺少空终止符导致的越界读取
  • 影响:行为不符合规范,程序可能崩溃(拒绝服务),且CONNECT请求可能被错误分类
  • 根本原因:复制方法字符串时未添加空终止符

受影响的代码路径

结构体布局:

1
struct httpreq { ... char method[1]; }

分配和复制(无NUL):

1
2
req = calloc(1, sizeof(*req) + m_len);
memcpy(req->method, method, m_len);

不安全的用法:

  • strcmp("CONNECT", req->method) — 假设字符串是空终止的
  • strlen(req->method) — 用于确定HTTP/2伪头部 :method 的大小

直接风险:如果req->method[m_len]越界,strcmpstrlen都可能访问超出已分配范围的内存。具体影响因分配器/布局而异;ASan总是会检测到这个问题。

复现步骤(简明)

前提条件:确保已安装CMake和nghttp2。

版本输出示例:

1
2
3
4
5
cmake --version
# → 3.26.2

pkg-config --modversion libnghttp2
# → 1.52.0

使用ASan + HTTP/2构建curl:

1
2
mkdir -p build && cmake -B build -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_FLAGS='-O1 -g -fsanitize=address' -DCMAKE_EXE_LINKER_FLAGS='-fsanitize=address' -DCURL_USE_NGHTTP2=ON
cmake --build build -j"$(nproc)"

验证二进制文件和功能:

1
./src/curl --version

影响

  • 拒绝服务/崩溃:在创建HTTP/2伪头部或检查CONNECT逻辑时发生越界读取。
  • 逻辑缺陷:由于对未初始化值进行比较,检测CONNECT的函数可能表现异常。

触发场景:任何生成struct httpreq(例如,自定义方法)并随后执行HTTP/2翻译或CONNECT检查的路径。

建议的修复方案(最小且稳健)

在两个创建函数中,不仅要添加空终止符,还要为其分配内存:

1
2
3
4
5
- req = calloc(1, sizeof(*req) + m_len);
+ req = calloc(1, sizeof(*req) + m_len + 1);
  if(!req) goto out;
  memcpy(req->method, method, m_len);
+ req->method[m_len] = '\0';
  • 需要修改的位置
    • Curl_http_req_make
    • Curl_http_req_make2

此更改消除了局部未定义读取,且不改变逻辑。可选加固:替换strcmp("CONNECT", ...)

后续讨论

bagder (curl staff) 在6天前发表评论: 感谢您的报告!我们将花些时间调查您的报告,并尽快向您反馈详情和可能的后续问题!很可能在24小时内。我们始终致力于尽快修复报告的问题。低或中严重性问题我们将合并到下一个常规发布周期中。只有更严重的问题我们才会提前发布修复。

bagder (curl staff) 在6天前发表评论: 根本原因:方法字符串在复制时未添加空终止符。这似乎是错误的分析。再看一下结构体。它是用calloc分配的。空终止符已经存在。

icing (curl staff) 在6天前发表评论: 确实,struct httpreqchar method[1];结尾,并且用结构体大小加上m_len进行了calloc,这为终止NUL字节留出了空间。

gaurav_7777 (ID验证的黑客) 在6天前发表评论: 嗨 Bagder,非常感谢您的快速回复! 我只是想确认没有误解。当您说“您的报告”和“我们将调查您的报告”时,您是指我的两个提交吗?

  1. 较早的DoS/崩溃报告
  2. 今天提交的新的SharePoint外部存储路径遍历报告 我只是想完全确定您正在调查哪一个(或哪些),以便我可以准备任何额外的信息或PoC(如果需要)。 再次感谢,期待您的更新!

bagder (curl staff) 在6天前关闭了报告并将状态更改为“不适用”: @gaurav_7777 我只能看到一个您提交的报告。就是这个。而且这不是一个安全问题。

gaurav_7777 (ID验证的黑客) 在6天前发表评论: 对不起对不起,非常抱歉,这是我的错。

gaurav_7777 (ID验证的黑客) 在6天前发表评论: 我想这应该是我另一份报告..!

bagder (curl staff) 在6天前请求公开此报告: 根据项目的透明性政策,我们希望所有报告都能被公开。

gaurav_7777 (ID验证的黑客) 在6天前取消了公开此报告的请求: 嗨 Bagder/团队 — 这份报告由于我的错误分析是不正确的;请不要公开披露它,保持它被撤回/关闭。

bagder (curl staff) 在6天前发表评论: 抱歉,但我们会在完成时披露每一份报告。大多数报告都是错误的。我们希望保持透明,这有助于每个人了解这里发生的情况。所以这份报告也将被披露。

gaurav_7777 (ID验证的黑客) 在6天前请求公开此报告: 好的,我理解项目政策。我同意披露此报告,并且我保证下次会为您带来一个有效且高影响的漏洞。

bagder (curl staff) 在6天前同意公开此报告。此报告已于6天前被披露。

报告元数据

  • 报告于:2025年11月20日,UTC 03:47
  • 报告者:gaurav_7777
  • 报告给:curl
  • 报告ID:#3434510
  • 严重性:高 (7 ~ 8.9)
  • 披露日期:2025年11月20日,UTC 09:20
  • 弱点类型:缓冲区过度读取
  • CVE ID:无
  • 赏金:隐藏
  • 账户详情:无
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计