HTTP响应拆分漏洞与防护
字数 1170 2025-11-11 03:10:35
HTTP响应拆分漏洞与防护
1. 漏洞描述
HTTP响应拆分(HTTP Response Splitting)是一种利用输入验证不足导致的CRLF(Carriage Return Line Feed,即\r\n)注入漏洞。攻击者通过向HTTP响应头中注入特殊字符,将单个响应拆分成多个恶意响应,从而实现缓存投毒、跨站脚本(XSS)、会话劫持等攻击。
2. 漏洞原理
关键点:CRLF控制字符
- HTTP协议使用
\r\n(十六进制0x0D 0x0A)作为头部字段的分隔符。 - 如果用户输入的数据未经处理直接拼接到HTTP响应头中(如
Location、Set-Cookie等),攻击者可注入\r\n并伪造新的响应头或响应体。
攻击示例场景
假设应用根据用户参数设置重定向URL:
HTTP/1.1 302 Found
Location: https://example.com/redirect?url=user_input
若user_input为:
https://evil.com%0D%0AContent-Length:%200%0D%0A%0D%0AHTTP/1.1%20200%20OK%0D%0AContent-Type:%20text/html%0D%0A%0D%0A<script>alert('XSS')</script>
解码后实际响应变为:
HTTP/1.1 302 Found
Location: https://evil.com
Content-Length: 0
HTTP/1.1 200 OK
Content-Type: text/html
<script>alert('XSS')</script>
服务器可能将注入内容视为第二个响应,导致客户端执行恶意脚本。
3. 漏洞挖掘方法
- 识别用户输入点:检查所有控制HTTP响应头的参数(如重定向URL、Cookie值、文件名等)。
- 测试CRLF注入:输入
%0D%0A(URL编码)或\r\n(其他场景),观察响应是否换行。 - 验证攻击效果:尝试注入完整的响应头(如
X-Header: test),确认服务器是否解析。
4. 防护方案
4.1 输入验证与过滤
- 禁止CRLF字符:对用户输入进行严格过滤,移除
\r、\n及其URL编码形式。 - 示例代码(Java):
String sanitizedInput = userInput.replaceAll("[\r\n]", "");
4.2 输出编码
- 在将数据拼接到HTTP头前,对特殊字符进行编码(如将
\r\n转为%0D%0A,但需确保编码后不被解析)。 - 更安全的做法是使用标准库设置响应头,避免手动拼接。
4.3 使用安全API
- 直接调用框架提供的API设置头部信息(如
response.setHeader("Location", url)),而非字符串拼接。
4.4 最小化依赖用户输入
- 避免将用户输入直接用于构造响应头。例如,重定向时使用预定义URL映射而非完整用户输入。
5. 进阶攻击变种
- HTTP请求走私(HTTP Request Smuggling):利用请求/响应解析差异,通过注入
Content-Length或Transfer-Encoding干扰代理服务器。 - 缓存投毒:通过拆分响应污染CDN缓存,使其他用户收到恶意内容。
6. 实战测试案例
- 使用工具(如Burp Suite)拦截含重定向参数的请求。
- 在参数中添加
%0D%0A测试响应是否拆分。 - 尝试注入
Set-Cookie头劫持会话。
通过以上步骤,可系统理解HTTP响应拆分的成因、危害及防护措施。实际开发中需严格遵循“永不信任用户输入”原则,结合自动化安全测试工具提前发现漏洞。