HTTP请求走私(HTTP Request Smuggling)攻击详解
字数 2275 2025-12-08 01:57:33

HTTP请求走私(HTTP Request Smuggling)攻击详解

1. 攻击描述
HTTP请求走私是一种利用HTTP/1.1规范中请求报文解析的差异性,通过构造一个“歧义”的HTTP请求,干扰前端服务器(如反向代理、负载均衡器)与后端服务器之间对请求边界的理解,从而破坏请求处理队列的攻击技术。攻击者可利用此漏洞获取其他用户的敏感请求、发起缓存投毒、绕过安全控制等。

2. 核心原理:消息边界解析差异

  • 前端服务器:通常作为流量入口,负责接收客户端连接,并将请求转发给一个或多个后端应用服务器。
  • 后端服务器:实际处理业务逻辑的服务器。
  • 问题根源:RFC 2616规定HTTP/1.1请求消息的边界由Content-LengthTransfer-Encoding两个头部字段定义。当前端与后端对这两个头部的解析优先级、处理顺序或规范遵循存在差异时,就会对同一个TCP连接中的多个请求的边界产生不同理解,导致请求“走私”到错误的上下文中。

3. 常见攻击类型与步骤详解

类型一:CL.TE走私(前端使用Content-Length,后端使用Transfer-Encoding)

  1. 攻击请求构造
    POST /victim-endpoint HTTP/1.1
    Host: target.com
    Content-Length: 13
    Transfer-Encoding: chunked
    
    0
    
    GET /malicious-action HTTP/1.1
    X-Injected: header
    
  2. 分步解析过程
    • 前端服务器解析:它优先信任Content-Length: 13。它计算从0开始到第一个空行后的字符数(即0\r\n\r\n),恰好是13个字节(字符0\r\n\r\n)。因此,前端认为整个请求体到此结束,并将这个完整的请求转发给后端。
    • 后端服务器解析:它优先信任Transfer-Encoding: chunked。它按照分块编码规则解析请求体。第一块是0,表示块大小为0,即请求体结束。所以,后端认为第一个请求在0\r\n\r\n后就结束了。而后续的GET /malicious-action...部分,后端会将其视为下一个独立的请求,等待当前连接上接收到的“下一个”请求。
  3. 攻击生效:当某个正常用户发送下一个合法请求时,后端服务器会将这个正常请求与之前等待的GET /malicious-action...拼接,导致该用户的请求被篡改或走私的请求被当作该用户的请求执行。

类型二:TE.CL走私(前端使用Transfer-Encoding,后端使用Content-Length)

  1. 攻击请求构造
    POST /victim-endpoint HTTP/1.1
    Host: target.com
    Content-Length: 3
    Transfer-Encoding: chunked
    
    8
    GET /404 HTTP/1.1
    
    0
    
  2. 分步解析过程
    • 前端服务器解析:它识别Transfer-Encoding: chunked。首先,它读取第一块大小8,然后读取接下来的8个字节(即GET /404 ),接着读取下一块大小0,表示请求体结束。因此,前端将整个构造的请求(包括GET /404 ...)作为一个完整的请求体,转发给后端。
    • 后端服务器解析:它忽略Transfer-Encoding,只认Content-Length: 3。它只读取请求体的前3个字节(即8\r\n),就认为当前请求的请求体结束了。而剩下的GET /404 HTTP/1.1\r\n\r\n0\r\n\r\n部分,后端会将其挂起,等待作为下一个请求的开始。
  3. 攻击生效:与CL.TE类似,当正常用户的下一个请求到达时,会被后端与挂起的GET /404 ...拼接处理。

类型三:TE.TE走私(前后端都支持Transfer-Encoding,但解析存在差异)
攻击者通过混淆、混淆Transfer-Encoding头部,诱发差异。

  1. 攻击请求构造
    POST /victim-endpoint HTTP/1.1
    Host: target.com
    Content-Length: 4
    Transfer-Encoding: chunked
    Transfer-Encoding: x
    
    5c
    ...恶意请求体...
    0
    
  2. 分步解析过程
    • 前端服务器处理:可能处理第一个Transfer-Encoding: chunked,按照分块编码解析。
    • 后端服务器处理:可能处理最后一个Transfer-Encoding: x(一个无效值),从而回退到使用Content-Length,或者因为重复头部而产生解析错误。这种不一致性同样可以制造请求边界歧义。

4. 攻击影响与利用场景

  • 窃取用户请求:将其他用户的请求(如含Cookie的请求)变为走私请求的“body”,转发给攻击者控制的服务器。
  • 绕过安全控制:前端有WAF(Web应用防火墙)或访问控制,但后端没有。走私一个前端认为合法、后端会执行的恶意请求,从而绕过防护。
  • 缓存投毒:走私一个能影响缓存内容的请求(如PURGE或特定GET请求),污染CDN或代理缓存,向其他用户分发恶意内容。
  • 反射型DDoS:走私大量请求到后端,消耗后端资源。

5. 防御机制

  • 前端服务器配置
    • 禁用到后端的连接复用(影响性能,不推荐)。
    • 对同一请求,严格使用Content-LengthTransfer-Encoding中的一个,并优先使用Content-Length(如果两者都存在,可视为非法请求并丢弃)。
    • Transfer-Encoding头部值进行规范化处理(如只接受小写的chunked,拒绝重复、畸形的头部)。
  • 后端服务器配置
    • 对接收到的请求进行严格的HTTP协议合规性验证。
    • 拒绝处理存在头部歧义或格式明显违规的请求。
  • 架构层面
    • 使用HTTP/2与后端通信。HTTP/2是二进制、分帧协议,有明确的消息边界,天然避免了此类问题。
    • 确保整个请求处理链(前端、WAF、后端)使用相同的HTTP解析库和配置。
  • 开发者注意:在应用层面,避免将单个HTTP请求的输入流(如req.body)与连接套接字直接关联的逻辑。
HTTP请求走私(HTTP Request Smuggling)攻击详解 1. 攻击描述 HTTP请求走私是一种利用HTTP/1.1规范中请求报文解析的差异性,通过构造一个“歧义”的HTTP请求,干扰前端服务器(如反向代理、负载均衡器)与后端服务器之间对请求边界的理解,从而破坏请求处理队列的攻击技术。攻击者可利用此漏洞获取其他用户的敏感请求、发起缓存投毒、绕过安全控制等。 2. 核心原理:消息边界解析差异 前端服务器 :通常作为流量入口,负责接收客户端连接,并将请求转发给一个或多个后端应用服务器。 后端服务器 :实际处理业务逻辑的服务器。 问题根源 :RFC 2616规定HTTP/1.1请求消息的边界由 Content-Length 和 Transfer-Encoding 两个头部字段定义。当前端与后端对这两个头部的解析优先级、处理顺序或规范遵循存在差异时,就会对同一个TCP连接中的多个请求的边界产生不同理解,导致请求“走私”到错误的上下文中。 3. 常见攻击类型与步骤详解 类型一:CL.TE走私(前端使用Content-Length,后端使用Transfer-Encoding) 攻击请求构造 : 分步解析过程 : 前端服务器解析 :它优先信任 Content-Length: 13 。它计算从 0 开始到第一个空行后的字符数(即 0\r\n\r\n ),恰好是13个字节(字符 0 、 \r 、 \n 、 \r 、 \n )。因此,前端认为整个请求体到此结束,并将这个完整的请求转发给后端。 后端服务器解析 :它优先信任 Transfer-Encoding: chunked 。它按照分块编码规则解析请求体。第一块是 0 ,表示块大小为0,即请求体结束。所以,后端认为第一个请求在 0\r\n\r\n 后就结束了。而后续的 GET /malicious-action... 部分,后端会将其视为 下一个独立的请求 ,等待当前连接上接收到的“下一个”请求。 攻击生效 :当某个正常用户发送下一个合法请求时,后端服务器会将这个正常请求与之前等待的 GET /malicious-action... 拼接,导致该用户的请求被篡改或走私的请求被当作该用户的请求执行。 类型二:TE.CL走私(前端使用Transfer-Encoding,后端使用Content-Length) 攻击请求构造 : 分步解析过程 : 前端服务器解析 :它识别 Transfer-Encoding: chunked 。首先,它读取第一块大小 8 ,然后读取接下来的8个字节(即 GET /404 ),接着读取下一块大小 0 ,表示请求体结束。因此,前端将整个构造的请求(包括 GET /404 ... )作为一个完整的请求体,转发给后端。 后端服务器解析 :它忽略 Transfer-Encoding ,只认 Content-Length: 3 。它只读取请求体的前3个字节(即 8\r\n ),就认为当前请求的请求体结束了。而剩下的 GET /404 HTTP/1.1\r\n\r\n0\r\n\r\n 部分,后端会将其挂起,等待作为 下一个请求 的开始。 攻击生效 :与CL.TE类似,当正常用户的下一个请求到达时,会被后端与挂起的 GET /404 ... 拼接处理。 类型三:TE.TE走私(前后端都支持Transfer-Encoding,但解析存在差异) 攻击者通过混淆、混淆 Transfer-Encoding 头部,诱发差异。 攻击请求构造 : 分步解析过程 : 前端服务器处理 :可能处理第一个 Transfer-Encoding: chunked ,按照分块编码解析。 后端服务器处理 :可能处理最后一个 Transfer-Encoding: x (一个无效值),从而回退到使用 Content-Length ,或者因为重复头部而产生解析错误。这种不一致性同样可以制造请求边界歧义。 4. 攻击影响与利用场景 窃取用户请求 :将其他用户的请求(如含Cookie的请求)变为走私请求的“body”,转发给攻击者控制的服务器。 绕过安全控制 :前端有WAF(Web应用防火墙)或访问控制,但后端没有。走私一个前端认为合法、后端会执行的恶意请求,从而绕过防护。 缓存投毒 :走私一个能影响缓存内容的请求(如 PURGE 或特定GET请求),污染CDN或代理缓存,向其他用户分发恶意内容。 反射型DDoS :走私大量请求到后端,消耗后端资源。 5. 防御机制 前端服务器配置 : 禁用到后端的连接复用(影响性能,不推荐)。 对同一请求,严格使用 Content-Length 和 Transfer-Encoding 中的一个,并优先使用 Content-Length (如果两者都存在,可视为非法请求并丢弃)。 对 Transfer-Encoding 头部值进行规范化处理(如只接受小写的 chunked ,拒绝重复、畸形的头部)。 后端服务器配置 : 对接收到的请求进行严格的HTTP协议合规性验证。 拒绝处理存在头部歧义或格式明显违规的请求。 架构层面 : 使用HTTP/2与后端通信。HTTP/2是二进制、分帧协议,有明确的消息边界,天然避免了此类问题。 确保整个请求处理链(前端、WAF、后端)使用相同的HTTP解析库和配置。 开发者注意 :在应用层面,避免将单个HTTP请求的输入流(如 req.body )与连接套接字直接关联的逻辑。