innerHTML和document.write是XSS高危入口,因直接解析用户输入为HTML/JS;应改用textContent或DOMPurify净化后赋值,禁用document.write,严格按上下文转义。

HTML 本身不执行逻辑,但它是 XSS、模板注入、DOM 污染等前端安全问题的主战场。排查重点不是“有没有漏洞”,而是“用户输入是否被当作代码执行”——只要动态拼接、未转义、未隔离,风险就已存在。
检查 innerHTML 和 document.write 的使用位置
这两个 API 是 XSS 最直接的入口。它们把字符串当 HTML 解析,一旦内容含用户输入,攻击者就能注入 <script>、<img onerror=> 等任意标签。
- 搜索项目中所有
innerHTML =、.insertAdjacentHTML(、document.write(调用,逐行确认右侧值是否完全可控(如来自location.search、localStorage、API 返回的评论字段) - 用
textContent替代innerHTML是最简单有效的修复方式;若必须渲染 HTML,需先过DOMPurify.sanitize() -
document.write在现代页面中基本无正当用途,尤其在 DOM 加载完成后调用会清空整个页面,应直接删除
验证 URL 参数和表单提交是否反射到页面
URL 中的 ?q=xxx、?msg=success 经常被直接插入 <div></div> 或作为 value 属性回显——这是反射型 XSS 的高发场景。
- 手动测试:在参数中填入
<svg onload=alert(1)>或"><img src=x onerror=alert(2)>,观察是否触发弹窗或生成未过滤的 DOM 节点 - 检查 JavaScript 中解析 URL 的逻辑,例如
new URLSearchParams(location.search).get('q')后是否未经处理就写入页面 - 服务端返回的 JSON 数据若被前端用
JSON.parse()后直接拼进 HTML 字符串(如`<h2>${data.title}</h2>`),同样危险
审查模板引擎中用户输入是否参与模板编译
模板注入(如 art-template、FreeMarker、Handlebars)比普通 XSS 更严重:它能让攻击者执行任意服务端逻辑或读取文件。关键判断标准是——用户输入有没有被当成模板语法解析?
立即学习“前端免费学习笔记(深入)”;
- 查
template.compile(userInput)、new Template(userInput)、res.render('page', { html: userInput })这类调用,只要userInput来自前端,就是高危 - 禁用模板引擎中的危险语法:art-template 的
{{= data}}、FreeMarker 的${data?eval}、Handlebars 的{{{html}}}都不能用于用户数据 - include 路径含用户输入(如
<#include file="${param.file}">)等于开放目录遍历,必须禁止
确认 CSP 头和沙箱配置是否生效
CSP 不是万能补丁,但它是最后一道防线。没配或配错,等于把门开着等攻击者进来。
- 打开浏览器开发者工具 → Network → 刷新页面 → 查看响应头中是否有
Content-Security-Policy,且包含script-src 'self'(禁止内联脚本和外部域脚本) - 若使用
<iframe>运行不可信 HTML,必须加sandbox属性,且不带allow-scripts;否则iframe内的eval或innerHTML仍可执行 - CSP 无法防御
javascript:伪协议或 DOM-based XSS,所以它必须和编码转义、输入隔离配合使用,不能单独依赖
真正容易被忽略的是:XSS 防护必须按上下文做差异化处理。插在 HTML 标签里要转义 <、>;插在属性值里要转义引号和 =;插在 JS 字符串里要用 JSON 编码;插在 URL 里得用 encodeURIComponent。用同一个函数处理所有场景,反而会漏掉关键逃逸路径。



















