应直接用curl抓原始HTML响应体排查注入,而非依赖浏览器DOM;若<script><iframe>等标签出现在源码未定义位置,且Content-Length增大、ETag不一致,则大概率是CDN或服务端被劫持。

直接看原始响应体,别信浏览器渲染后的 DOM —— 大部分注入脚本是服务端或 CDN 层硬塞进去的,浏览器里看到的已经是“被污染后的结果”。
用 curl 抓原始 HTML 响应体查注入痕迹
很多团队在开发者工具里翻 Elements 面板找 <script>,却漏掉真正的问题源头。恶意标签往往在 HTTP 响应体里就已存在,根本没经过 JS 执行。
- 执行
curl -s https://yoursite.com/ | head -n 100,搜索<script、<iframe、<base、onerror=、javascript:等关键词 - 若这些标签出现在你源码模板里根本没写的位置,说明不是前端 XSS,而是服务端输出或 CDN 缓存被污染
- 对比
Content-Length:正常首页响应体约 25KB,注入后常变成 25.8KB 左右——多出的几百字节大概率是恶意脚本 - 检查
ETag值是否与源站一致;不一致 + 内容变长 = CDN 或中间代理篡改了响应
区分 DOM 型 XSS 和第三方注入的关键动作
DOM 型 XSS 是前端 JS 自己把 location.search 拼进 innerHTML;而第三方注入是服务器返回的 HTML 里已经带毒。两者修复路径完全不同。
- 禁用 CDN 测试:改
/etc/hosts直连源站 IP,问题消失 → 锁定 CDN 劫持 - 换出口 IP 测试:用不同地区代理(如
curl -x http://proxy-jp.example:8080)访问,仅部分节点异常 → 是 CDN POP 点配置漏洞,非全局问题 - 打开 Chrome 无痕窗口,禁用所有插件再访问;若仍有异常弹窗或未知请求 → 排除浏览器插件干扰
- 在 Network 面板中查看
Initiator列:如果某个<script src>的发起者是html而非 JS 文件,说明它来自 HTML 原始响应,不是运行时动态加载
服务端模板中哪些输出点最容易被利用
攻击者不靠 <script> 标签也能注入,只要能闭合属性引号、拼接事件处理器或 URL 协议即可。关键看用户输入落在哪个上下文。
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
立即学习“前端免费学习笔记(深入)”;
- 在 HTML 元素内容中(如
<div>{user_input}</div>):必须转义<、>、&、"、'—— Python 用html.escape(input, quote=True),PHP 用htmlspecialchars($input, ENT_QUOTES) - 在属性值中(如
<input value="{user_input}">):除了上述五字符,还要确保引号匹配(双引号包裹时,"必须转义;单引号则处理') - 在 JS 字符串中(如
var msg = "{user_input}";):必须用JSON.stringify(),不能只替换引号 —— 否则\u2028或换行会破坏语法 - 在 URL 中(如
<a href="{user_input}">):需先校验协议白名单(http、https、/),再做 URL 编码,不能只依赖encodeURIComponent
为什么 DOMPurify 不调用等于没装
引入 DOMPurify 脚本但不调用 DOMPurify.sanitize(),和没装一样危险。它的默认策略已禁用 onerror、javascript:、<script>,但前提是你要让它跑起来。
- 错误写法:
el.innerHTML = userInput→ 直接执行 - 正确写法:
el.innerHTML = DOMPurify.sanitize(userInput)→ 白名单过滤后插入 - 服务端同理:Python 用
bleach.clean(),Node.js 用sanitize-html,都必须显式传入tags、attributes、protocols白名单 - 注意
v-html(Vue)和dangerouslySetInnerHTML(React):这两个 API 本身不带净化逻辑,必须在外层手动套用净化函数,否则等同于裸奔
最常被忽略的是:CDN 回源未校验证书、cache_key 包含 query_string、Edge Function 拼接 header 未转义 —— 这些环节一旦失守,你前端再怎么转义都没用。排查必须从网络层开始,而不是一上来就改 JS。


















