curl Alt-Svc 特性绕过认证凭证保护机制详解

本报告详细描述了curl库中Alt-Svc实现的一个安全问题:在进行主机或端口重映射时,未能剥离敏感的认证头信息(如Authorization和Cookies),从而绕过了为CVE-2018-1000007设立的安全防护。报告包含问题分析、复现步骤及影响评估。

Alt-Svc 绕过凭证泄露防护 (CVE-2018-1000007)

报告时间: 2026年1月3日,下午4:30 (UTC) 报告人: amik_f 报告给: curl 报告ID: #3485826 严重性: 高 (7 ~ 8.9) 弱点: 通过发送的数据泄露信息 CVE ID: CVE-2018-1000007

摘要

我发现了一个bug,curl的Alt-Svc实现在将连接重新映射到不同的主机或端口时,未能剥离敏感的认证头信息(Authorization和Cookies)。这实质上绕过了为CVE-2018-1000007设立的安全修复。

在审计代码时,我注意到lib/url.c中的Alt-Svc重映射会更新 conn->conn_to_host.nameconn->conn_to_port,但lib/vauth/vauth.c中的认证守卫函数(Curl_auth_allowed_to_host)只检查原始的 conn->host.nameconn->remote_port

此外,Alt-Svc重映射没有设置 data->state.this_is_a_follow 标志。由于认证守卫只在该标志为TRUE时才激活,因此Alt-Svc“重定向”完全绕过了凭证保护逻辑。

受影响版本

curl 8.17.0 (x86_64-pc-linux-gnu) libcurl/8.17.0 OpenSSL/3.5.4 (在Kali Linux上测试,但影响所有启用了Alt-Svc的版本)

复现步骤

我附上了一个复现脚本 final_comparison_poc.py,通过比较标准的302重定向(安全)与Alt-Svc重映射(泄露凭证)来演示该问题。

  1. 在端口8443(生产环境)和端口9443(攻击者)上设置监听器。
  2. 使用凭证和指向localhost:9443的Alt-Svc头请求 https://localhost:8443/。
  3. 使用Alt-Svc缓存对同一URL进行第二次请求。
  4. 观察到凭证被发送到端口9443。

支持材料/参考文献

我已在源代码中验证了代码不匹配的问题: 在 lib/vauth/vauth.c 中:

1
2
3
4
5
return !data->state.this_is_a_follow ||
       data->set.allow_auth_to_other_hosts ||
       (data->state.first_host &&
        curl_strequal(data->state.first_host, conn->host.name) &&
        (data->state.first_remote_port == conn->remote_port) ...

修复应涉及检查Alt-Svc处理的有效主机/端口,类似于url.c:3235中的模式:

1
2
3
4
const char *check_host = conn->bits.conn_to_host ?
                         conn->conn_to_host.name : conn->host.name;
int check_port = conn->bits.conn_to_port ?
                 conn->conn_to_port : conn->remote_port;

影响

摘要

控制HTTPS服务器的攻击者可以通过提供恶意的Alt-Svc头,从客户端窃取敏感的Authorization头和会话Cookies。由于curl会缓存Alt-Svc条目,这种泄露是持久性的,将影响未来对同一源的请求,即使这些请求在其他情况下是安全的。这直接绕过了CVE-2018-1000007建立的安全边界。

时间线与讨论

  • 8天前: amik_f 向curl提交报告。
  • 8天前: bagder (curl 工作人员) 评论:替代服务是在另一个地方的相同服务,它不是重定向。它应该获得相同的头信息。我不认为这是个问题。
  • 8天前: amik_f 回应:RFC 7838 2.1 明确指出 Alt-Svc 并非与源“同源”。Curl 对从端口 8443 到 9443 的 302 重定向会剥离凭证(CVE-2018-1000007),但 Alt-Svc 目前绕过了这一点。我的PoC显示端口 9443 拦截了生产环境凭证,因为 Alt-Svc 没有设置 this_is_a_follow 标志,导致 vauth.c 的守卫未激活。不同的端口不应自动被信任接收生产环境的会话cookies。
  • 8天前: bagder 关闭报告并将状态改为“不适用”。评论:RFC 7838 2.1 明确指出 Alt-Svc 并非与源“同源”。什么?不,它当然没有这么说。这是相同的服务,只是在另一个主机/协议/端口上。这不是一个安全问题。这就是 alt-svc 的工作方式。
  • 8天前: bagder 请求披露此报告。根据项目的透明度政策,我们希望所有报告都被公开披露。
  • 7天前: amik_f 评论:感谢您的反馈…我理解 Alt-Svc 旨在实现传输透明性,但它目前绕过了您为重定向建立的安全策略。 关键问题: 为什么 curl 会为从端口 8443 到端口 9443 的 302 重定向剥离凭证(以防止泄露),却为相同的两个端口之间的 Alt-Svc 重映射发送凭证? 我的PoC证实端口 9443 通过 Alt-Svc 接收了生产环境凭证,纯粹是因为 vauth.c 守卫从未看到重映射。这创建了一个到不同源/端口的“静默重定向”,而 curl 通常会将这样的目标视为凭证的不可信方。
  • 7天前: bagder 评论:因为这就是 alt-svc 的工作方式。如果 curl 禁止该特性,就会破坏 alt-svc 的全部目的。 您可以通过 A) 再次阅读规范 和 B) 与其他 alt-svc 客户端(如网络浏览器)的行为进行比较来了解这一点。 如果您对 curl 的 alt-svc 实现和支持有更多疑问,这里不是继续讨论的地方。请移步公共论坛。
  • 7天前: bagder 披露了此报告。
  • 7天前: jimfuller2024 (curl 工作人员) 评论:RFC 7838 中没有任何地方说要“剥离敏感头信息”… 由于缺乏明确的指导——我们依赖于集体行为导致“最不意外的结果”… 当然,所有这些都是在关注安全的前提下完成的。有很多地方(包括 curl irc, github 等)可以讨论是否可以进行任何改进——但这里没有安全漏洞,例如,这是预期的工作行为。

披露时间: 2026年1月4日,上午10:34 (UTC) 赏金: 无 账户详情: 无

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计