HTTP Request Smuggling 研究笔记
本文是我对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长度判断不一致时,攻击者可以构造一个特殊的请求,使得:
- 前端服务器认为这是一个完整的请求并转发
- 后端服务器只消费部分body
- 剩余的部分被当作下一个请求的开头
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项目。
检测方法
- 发送带有CL和TE双头部的请求,其中CL值偏小
- 观察响应时间 – 如果后端等待更多chunked数据会导致超时
- 发送完整的走私payload,观察后续请求是否受到影响
- 使用时间差异(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)