cURL HTTP请求走私漏洞深度分析

本文详细分析了cURL中存在的HTTP请求走私漏洞,该漏洞源于同时处理Transfer-Encoding和Content-Length头时的不一致行为,可能导致认证绕过、缓存投毒等安全问题,包含完整的技术细节和复现步骤。

HTTP请求走私漏洞分析 - cURL安全报告

摘要

cURL未明确拒绝同时包含Transfer-Encoding和Content-Length头的HTTP请求,当这些请求通过解释头方式与目标服务器不同的中间系统(代理、负载均衡器、防火墙)时,可能导致HTTP请求走私漏洞(CWE-444)。这种不一致的解释使攻击者可能绕过安全控制走私恶意请求或导致缓存投毒攻击。

该漏洞源于http.c中的http_req_set_reader()函数,该函数处理Transfer-Encoding头时未验证是否存在冲突的Content-Length头。虽然cURL内部优先处理Transfer-Encoding而非Content-Length,但不会移除或拒绝冲突的Content-Length头,导致两个头同时被发送。

注意:本漏洞分析通过手动代码审查cURL源代码完成,使用AI辅助构建和格式化本漏洞报告。

受影响版本

该漏洞影响包含当前HTTP请求处理实现的cURL版本。测试环境包括:

  • cURL版本:8.4.0(curl-master分支)
  • 平台:Windows 10, Linux Ubuntu 20.04
  • libcurl版本:8.4.0
  • 协议:HTTP/1.1, HTTP/2
  • 特性:SSL, 分块传输编码

检查版本命令:

1
curl -V

复现步骤

  1. 创建包含冲突头的测试HTTP请求:
1
2
3
4
5
curl -v -X POST \
  -H "Transfer-Encoding: chunked" \
  -H "Content-Length: 100" \
  -d "0\r\n\r\nSMUGGLED_PAYLOAD" \
  http://example.com/test
  1. 观察cURL发送两个头而不拒绝:
  • 使用-v标志监控实际HTTP请求
  • 确认Transfer-Encoding: chunked和Content-Length: 100头同时存在
  • 注意cURL使用分块编码处理请求同时保留Content-Length头
  1. 使用代理设置演示走私可能性:
1
2
3
4
5
6
7
8
# 设置优先解释Content-Length的测试代理
# 然后通过代理发送冲突头
curl -v --proxy http://test-proxy:8080 \
  -H "Transfer-Encoding: chunked" \
  -H "Content-Length: 50" \
  -X POST \
  -d "0\r\n\r\nPOST /admin HTTP/1.1\r\nHost: target.com\r\n\r\n" \
  http://target.com/public
  1. 使用Python脚本自动化测试:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import subprocess

def test_smuggling():
    cmd = [
        "curl", "-v", "--include",
        "-H", "Transfer-Encoding: chunked",
        "-H", "Content-Length: 200",
        "-X", "POST",
        "-d", "0\r\n\r\nGET /smuggled HTTP/1.1\r\nHost: example.com\r\n\r\n",
        "http://example.com/endpoint"
    ]

    result = subprocess.run(cmd, capture_output=True, text=True)
    print("STDOUT:", result.stdout)
    print("STDERR:", result.stderr)

test_smuggling()
  1. 通过检查HTTP流量验证漏洞:
  • 使用Wireshark等工具捕获实际HTTP请求
  • 确认冲突头同时存在于网络协议中
  • 对不同服务器/代理测试相同请求以观察不同解释

支持材料/参考文献

  • 源代码分析:http.c - http_req_set_reader()函数和http_req_complete()函数审查
  • CWE分类:CWE-444 - HTTP请求不一致解释(‘HTTP请求/响应走私’)
  • CVSS评分:6.5(中危) - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:L
  • 概念验证脚本:演示漏洞的Python脚本(包含在上述步骤中)
  • 网络流量捕获:Wireshark/tcpdump捕获显示同一请求中的两个头
  • RFC参考:
    • RFC 7230 Section 3.3.3 (消息体长度)
    • RFC 7230 Section 3.3.1 (传输编码)
  • 类似CVE:
    • CVE-2019-16276 (Node.js HTTP请求走私)
    • CVE-2020-11946 (多种web服务器中的HTTP请求走私)
  • 安全研究:James Kettle的"HTTP异步攻击:请求走私重生"白皮书
  • 测试环境:具有不同代理配置的Docker容器用于测试头解释差异

影响

攻击者利用此HTTP请求走私漏洞可实现以下重大安全影响:

  1. 认证绕过
  • 通过绕过认证机制走私请求到受保护端点
  • 无需凭证访问管理接口或敏感API
  • 通过不同认证上下文路由请求提升权限
  1. 缓存投毒
  • 通过将恶意内容与合法URL关联毒害web缓存和CDN
  • 为后续请求缓存资源的用户提供恶意内容
  • 操纵缓存响应注入恶意脚本或重定向用户
  1. 请求劫持
  • 在共享代理环境中拦截和修改其他用户请求
  • 从共享同一连接的其他用户请求中窃取敏感数据
  • 操纵会话令牌和认证凭证
  1. 防火墙和安全控制绕过
  • 通过在走私请求中隐藏恶意负载规避Web应用防火墙(WAF)
  • 绕过中间设备实现的速率限制和访问控制
  • 逃避安全监控和日志系统
  1. 会话劫持
  • 通过走私看似来自合法用户的请求操纵会话管理
  • 通过拦截认证令牌劫持用户会话
  • 以合法用户身份执行未授权操作
  1. 数据泄露
  • 通过走私请求到内部API或数据库访问敏感数据
  • 绕过数据丢失防护(DLP)系统
  • 通过精心构造的走私请求提取机密信息
  1. 跨站脚本(XSS)和注入攻击
  • 通过缓存投毒向响应中注入恶意脚本
  • 通过走私数据库查询执行SQL注入攻击
  • 通过毒害缓存内容执行存储型XSS攻击

影响严重性:中到高,取决于网络架构和安全控制措施。该漏洞在具有多层代理、CDN或共享托管基础设施的环境中尤其危险。

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