核心问题
当服务器同时支持 Content-Length 和 Transfer-Encoding 两种方式来标识请求体长度时,如果处理不当,前后端系统对同一个请求的理解可能出现分歧,攻击者可以利用这种分歧实现请求走私。
具体造成的问题
1. HTTP请求走私(HTTP Request Smuggling)
这是最严重的安全问题。攻击者构造一个特殊的请求,使前端代理服务器和后端应用服务器对这个请求的解析不一致:
攻击示例:
text
POST /api HTTP/1.1 Host: example.com Content-Length: 13 Transfer-Encoding: chunked 0 GET /admin HTTP/1.1
-
前端代理可能优先使用
Transfer-Encoding,认为请求体以0结束 -
后端服务器可能优先使用
Content-Length,认为请求体长度为13字节 -
结果:后端的剩余字节(
GET /admin...)会被当作下一个请求处理
2. 安全绕过
-
身份验证绕过:走私的请求可能绕过认证机制
-
访问控制绕过:访问本应受保护的资源
-
缓存投毒:污染缓存服务器
-
反射型XSS增强:将走私的请求反射给其他用户
3. 系统混乱和拒绝服务
-
后端服务器可能处理错误的请求
-
请求/响应错位,导致应用逻辑混乱
-
可能造成拒绝服务(DoS)状态
技术细节
优先级冲突
RFC规范没有明确规定当两者同时出现时的优先级,不同服务器的实现不同:
-
一些服务器优先使用
Transfer-Encoding -
一些服务器优先使用
Content-Length -
一些服务器可能同时检查两者,但逻辑不一致
常见的混淆场景
| 攻击类型 | 前端理解 | 后端理解 |
|---|---|---|
| CL.TE冲突 | Content-Length | Transfer-Encoding |
| TE.CL冲突 | Transfer-Encoding | Content-Length |
| TE.TE冲突 | Transfer-Encoding的一种变体 | Transfer-Encoding的另一种变体 |
防御措施
1. 服务器端
-
禁用其中一种方法(通常禁用Transfer-Encoding)
-
明确指定优先级并严格实现
-
拒绝同时包含两种头部的请求
-
使用HTTP/2(有明确的帧边界定义)
2. 代理配置
-
标准化请求格式
-
在代理层验证请求一致性
-
使用相同的解析库确保前后端解析一致
3. 开发实践
-
使用成熟的HTTP库而不是自己解析
-
定期进行安全测试,包括请求走私测试
-
监控异常的请求模式
这个问题在HTTP/1.1中尤其突出,HTTP/2使用帧机制从根本上解决了这个问题,但在HTTP/1.1向后兼容的环境中仍然存在风险。