less than 1 minute read

本文是我对HTTP请求走私(HTTP Request Smuggling)技术的研究记录。英文版本请参考HTTP Request Smuggling - A Complete Guide。

背景

HTTP请求走私利用前端服务器(front-end)和后端服务器(back-end)之间对HTTP报文边界解析的差异。根据RFC 7230 Section 3.3.3,当请求同时包含Content-Length和Transfer-Encoding头部时,Transfer-Encoding应当优先。但不同的HTTP实现对此规则的遵守程度不同。

基本原理

当两台服务器对同一个HTTP请求的body长度判断不一致时,攻击者可以构造一个特殊的请求,使得:

  1. 前端服务器认为这是一个完整的请求并转发
  2. 后端服务器只消费部分body
  3. 剩余的部分被当作下一个请求的开头

CL.TE 变体

前端使用Content-Length,后端使用Transfer-Encoding:

POST / HTTP/1.1
Host: target.com
Content-Length: 13
Transfer-Encoding: chunked

0

SMUGGLED

前端根据Content-Length读取13字节并全部转发。后端按chunked解码,遇到0终止符后停止,”SMUGGLED”被保留在连接中作为下一个请求的起始。

TE.CL 变体

前端使用Transfer-Encoding,后端使用Content-Length:

POST / HTTP/1.1
Host: target.com
Content-Length: 3
Transfer-Encoding: chunked

8
SMUGGLED
0

前端处理完整的chunked body后转发。后端只读取3字节,剩余的”SMUGGLED\r\n0\r\n”成为下一个请求。

TE.TE 混淆变体

通过混淆Transfer-Encoding头部,使一台服务器能识别而另一台不能:

Transfer-Encoding: xchunked
Transfer-Encoding : chunked
Transfer-Encoding: chunked
Transfer-Encoding: x

实验环境

我搭建了一个包含多种代理/服务器组合的实验环境,用于系统性地测试各种走私变体。测试覆盖了Nginx, Apache, HAProxy, Gunicorn, Waitress等常见HTTP实现。

在测试过程中,我发现Waitress (Python WSGI server) 存在一个请求走私漏洞。当Waitress作为后端时,特定的CL.TE payload可以成功走私请求。我已将此问题报告给Pylons项目。

检测方法

  1. 发送带有CL和TE双头部的请求,其中CL值偏小
  2. 观察响应时间 – 如果后端等待更多chunked数据会导致超时
  3. 发送完整的走私payload,观察后续请求是否受到影响
  4. 使用时间差异(timing differential)来区分CL.TE和TE.CL

攻击场景

  • 绕过前端WAF规则
  • 劫持其他用户的请求
  • Web缓存投毒
  • 获取其他用户的认证信息

防御建议

  • 尽可能使用HTTP/2端到端通信
  • 在前端代理上配置严格的请求规范化
  • 拒绝同时包含CL和TE的请求
  • 监控异常的请求模式

参考文献

  • James Kettle, “HTTP Desync Attacks: Request Smuggling Reborn” (PortSwigger, 2019)
  • RFC 7230 Section 3.3.3
  • Amit Klein, “HTTP Request Smuggling” (2005)