dom型xss漏洞源于前端脚本将用户可控数据未经安全处理直接写入dom敏感位置(如innerhtml、eval),完全在浏览器端发生,不依赖服务器;防御需聚焦输入净化、输出转义及csp策略三重设防。

前端安全漏洞不是“有没有”的问题,而是“在哪、多深、是否被绕过”的问题。绝大多数 XSS、CSRF、图片 src 漏洞,都源于对用户输入的轻信和对输出上下文的误判——修复不靠堵单个入口,而靠在输入验证、输出转义、CSP 策略三个环节同时设防。
如何快速定位 DOM 型 XSS 的高危点
DOM 型 XSS 不经过服务器,纯前端 JS 操作触发,所以排查必须聚焦在 document.location、document.URL、document.referrer 这类可被污染的源,以及直接写入 DOM 的操作上。
- 重点检查所有使用
innerHTML、outerHTML、document.write()、eval()、setTimeout()(传字符串参数时)的地方 - 警惕 URL 参数解析逻辑:比如
new URLSearchParams(window.location.search).get('q')后直接塞进element.innerHTML - Chrome 开发者工具「元素」面板里看渲染结果是否含未转义的
<script></script>或onerror=类属性;「控制台」里手动执行location.href='?x=<script>alert(1)</script>'观察是否弹窗
img src 属性怎么防 javascript: 和 data: 注入
src 看似只是加载图片,但若值来自用户输入或拼接生成,就可能变成 XSS 或 SSRF 入口。浏览器对 javascript: 伪协议已有一定拦截,但 data:image/svg+xml;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg== 这类 SVG 载荷仍能执行脚本。
- 服务端接收 src 值后,必须校验协议:只允许
http、https、//(协议相对),明确拒绝javascript:、data:、vbscript: - 对域名做白名单匹配,而非简单字符串包含(避免
attacker.com.evil.com绕过) - 前端渲染前,用正则过滤掉可疑片段:
src.replace(/^(javascript|data|vbscript):/i, ''),但该过滤必须在服务端也做一遍——前端 JS 可被禁用或绕过 - 更稳妥的做法是:不传完整 URL,只传资源 ID,由后端拼出带签名的 CDN 地址,如
https://img.example.com/abc123?token=xxx
CSP 头配置为什么经常失效
Content-Security-Policy 是防御 XSS 的最后一道硬隔离,但它容易因配置宽松、遗漏指令或未覆盖全部上下文而形同虚设。
- 常见错误是只配了
script-src 'self',却忘了加unsafe-inline会放行所有内联脚本(包括<script>alert(1)</script>和onclick="...") -
img-src指令缺失时,恶意<img src="javascript:...">就不会被拦截;frame-ancestors缺失则无法防点击劫持 - 开发环境常通过 meta 标签注入 CSP,但该方式不支持
report-uri和report-to,且会被 JS 动态修改覆盖 - 必须配合
Content-Security-Policy-Report-Only先灰度运行,收集违规报告,再收紧策略——直接上线易导致功能异常
为什么 htmlspecialchars() 在 JS 上下文里不管用
htmlspecialchars() 只对 HTML 正文和属性上下文有效。一旦你把用户数据塞进 <script></script> 标签内部、或作为 JS 变量赋值,它就完全失效——因为浏览器先解析 HTML,再执行 JS,而 被转义后只是字符串,JS 引擎照常执行里面的代码。
- 在 HTML 中输出 JS 变量时,必须用
json_encode($value, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT)(PHP)或JSON.stringify()(服务端预处理) - 避免在模板中写
<script>var name = "<?php echo $_GET['name']; ?>"</script>,应改为<script>var name = <?php echo json_encode($_GET['name'], JSON_UNESCAPED_UNICODE); ?></script> - React/Vue 等框架默认转义插值内容,但显式使用
v-html或dangerouslySetInnerHTML时,等同于开闸放水,必须前置净化
真正难防的不是已知 payload,而是那些绕过双写过滤、大小写混淆、Unicode 编码、或利用浏览器解析差异的边缘 case。所以别只测 <script></script>,要跑全量 XSS 测试用例,尤其关注 DOM 操作链路中“输入→解析→拼接→写入”的每一步是否可控、是否被二次解码。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











