应优先用textcontent渲染纯文本以防止xss,必须插入html时须经dompurify等白名单净化;禁止将未经处理的input.value、url参数、json数据直接赋值给innerhtml、v-html或dangerouslysetinnerhtml。

输入框值直接拼进innerHTML会触发XSS
只要用户输入内容未经处理就赋给element.innerHTML,浏览器就会解析执行其中的标签和事件。比如在评论区、搜索高亮、后台富文本预览等场景,input.value或textarea.value被直接塞进innerHTML,就是最典型的漏洞入口。
常见错误写法:
const input = document.querySelector('#comment');
const output = document.querySelector('#display');
output.innerHTML = input.value; // 危险!
测试时输入<img src="x" onerror="alert(1)">,页面弹窗即确认漏洞存在。
- 不要用
innerHTML、insertAdjacentHTML()、document.write()接收任意输入 - 若需保留格式,必须先过
DOMPurify.sanitize()白名单过滤,不能只靠正则删<script></script> -
textContent安全但仅限纯文本——它不渲染任何 HTML,但也不支持<b></b>这类格式
URL参数反射到页面未转义是反射型XSS高发点
很多搜索页、错误提示页会把location.search里的q或msg参数直接插入 DOM,例如?q=%3Cscript%3Ealert(1)%3C/script%3E解码后渲染,就构成反射型 XSS。
排查方法:
- 手动修改 URL 参数,插入
<script>alert(1)</script>或<img src="x" onerror="fetch('/log?c='+document.cookie)"> - 检查开发者工具 Elements 面板,看该参数是否原样出现在 HTML 中(未被
<等实体编码) - 注意:有些前端框架(如 Vue)对
v-html绑定不做自动转义,{{ q | safe }}这类模板写法也属高危
富文本编辑器输出未净化等于主动放行XSS
富文本不是“例外”,而是风险集中区。用户提交的<p onclick="fetch('/admin/delete')">正文</p>或<img src="x" onerror="alert(1)">,如果后端只做htmlspecialchars()存储、前端再用dangerouslySetInnerHTML渲染,onerror 仍会执行。
关键判断点:
-
strip_tags()不校验属性,htmlspecialchars()不解析结构,二者都不能用于富文本 - 必须使用上下文感知的净化库:
DOMPurify(前端)、bleach(Python)、sanitize-html(Node.js),并显式配置白名单 - 白名单要细粒度控制:比如允许
<a></a>但限制href协议为http、https、/,禁用javascript:
JSON数据插入<script>标签前未做JS上下文编码</script>
后端返回 JSON 给前端,常被写成<script>window.data = ${JSON.stringify(userInput)};</script>。一旦userInput含"或,就会提前闭合标签,导致后续 JS 执行。
正确做法不是避免 JSON,而是按上下文编码:
- 在 HTML 属性中插 JSON:用
htmlEscape(如 Go 的html/template) - 在
<script></script>内插 JSON:用jsEscaper(Go)或 JavaScript 的JSON.stringify()+replace()处理和\u2028/\u2029 - 绝对不要把用户输入拼进
eval()、setTimeout()字符串参数或new Function()
最易被忽略的是:JSON 本身安全,但一旦离开 JSON 上下文(比如JSON.parse()后再拼 HTML),就必须立刻按目标上下文重新转义——不能假设“刚解析完的数据还是干净的”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











