结论:三型的区别在于恶意脚本从哪里来、经谁的手进入页面:反射型——脚本藏在 URL 参数里被服务端原样拼进响应(钓鱼链接点击触发,一次性);存储型——脚本先存进服务端(评论、昵称),每个访问者都触发(危害最大);DOM 型——不经过服务端,前端 JS 把不可信数据(location.hash 等)写入危险 sink(innerHTML、eval)造成,纯浏览器内闭环。
展开:防御分通用与专项:通用底座是输出编码——按上下文(HTML 文本、属性、JS 字符串、URL)分别转义,&<>"' 在文本节点转义、JS 上下文用 \u 转义,绝不能一个 htmlspecialchars 通吃所有场景。专项:1)反射/存储型——服务端模板默认自动转义(React JSX、Vue 插值天然安全),富文本场景用 DOMPurify 白名单过滤而非黑名单;2)DOM 型——审计 source(location、postMessage、document.referrer)到 sink 的数据流,用 textContent 替代 innerHTML,禁 eval/new Function;3)纵深——CSP(script-src 白名单/nonce)作为注入成功后的最后防线。易错点:属性值里的 javascript: URL、SVG/MathML 命名空间内的脚本、JSON 内嵌进 script 标签时 </script> 闭合逃逸,都是常规转义的盲区。
追问方向:mutation XSS(mXSS,浏览器规范化 HTML 时"洗白"产物变异成攻击载荷)、Trusted Types 如何根治 DOM XSS。