http请求走私是利用前后端对content-length与transfer-encoding解析不一致导致消息边界歧义的协议层攻击;nginx需禁用chunked、清除te头、拦截冲突请求并标准化边界处理。

HTTP 响应拆分(Response Splitting)和请求走私(Request Smuggling)都属于协议层逻辑漏洞,不依赖代码执行,而是利用前后端对 HTTP 消息边界的解析差异达成攻击。Nginx 作为反向代理时若配置不当,极易成为这类攻击的跳板。防范关键在于统一解析行为、清除歧义字段、拒绝非法组合。
禁用并清除 Transfer-Encoding 头
Transfer-Encoding: chunked 是请求走私最常利用的头部。Nginx 默认不主动解析入向 chunked 请求(除非启用 chunked_transfer_encoding on),但若上游有 WAF 或 CDN 解包后透传,或后端自行解码,就可能产生分歧。
- 在
http或location块中显式关闭:chunked_transfer_encoding off;(Nginx ≥ 1.13.6) - 强制清除客户端携带的该头:
proxy_set_header Transfer-Encoding ""; - 避免后端再次解码:确保后端服务(如 Spring Boot、Express)禁用自身 chunked 解析,只接收完整 body
拦截 Content-Length 与 Transfer-Encoding 冲突请求
当一个请求同时包含 Content-Length 和 Transfer-Encoding(尤其是值为 chunked)时,已构成协议违规,必须拒绝。
- 用
if+return在请求进入代理前拦截:if ($http_transfer_encoding ~* "chunked") { return 400; } - 更严谨的做法是检查两者共存:
if ($http_content_length && $http_transfer_encoding) { return 400; } - 注意:该判断需放在
location块内,且不能嵌套在if中调用proxy_pass
标准化响应头与消息边界
响应拆分多由攻击者注入 %0d%0a(CRLF)到响应头中触发,例如通过可控的 Redirect 或 Set-Cookie 字段。Nginx 本身不校验响应头内容,但可通过配置降低风险:
- 禁用动态拼接响应头:避免在
add_header中使用未过滤的变量(如$arg_xxx) - 统一设置
Content-Length:后端返回响应时务必带准确长度,避免 Nginx 自动转为 chunked 输出 - 开启
underscores_in_headers off;,防止大小写混淆绕过(如transfer-encoding与Transfer-Encoding被不同组件识别)
启用安全响应头并限制危险方法
虽不直接防御走私,但能缩小攻击面、增强整体健壮性:
- 禁止非必要 HTTP 方法:
if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|OPTIONS|PATCH)$) { return 405; } - 添加基础安全头:
add_header X-Content-Type-Options "nosniff" always;、add_header X-Frame-Options "DENY" always; - 隐藏服务器标识:
server_tokens off;,减少版本相关漏洞被定向利用的风险











