最有效阻断DOM事件型XSS的手段是配置严格CSP策略:禁用'unsafe-inline'和'unsafe-eval',使用'self'或'none'限制script-src,配合nonce/哈希白名单、限制DOM写入源头及同步做好前端转义与服务端编码。
直接配置严格的 csp 策略,是阻断 dom 事件型 xss 最有效、最底层的手段——它不依赖 js 逻辑是否写对,而是让浏览器从执行源头禁止非法行为。
明确禁用内联脚本与危险 DOM 操作
DOM 事件注入(如 onclick="alert(1)"、onload=javascript:...)本质依赖浏览器执行内联代码。CSP 的 script-src 指令可彻底切断这一路径:
- 必须移除
'unsafe-inline'和'unsafe-eval'—— 这两个值等于主动打开后门 - 使用
script-src 'self';或更严的script-src 'none';(若页面完全不执行 JS) - 禁用所有内联事件处理器:CSP 会自动拦截
onclick、onmouseover等 HTML 属性中的脚本,无需额外 JS 逻辑
用 nonce 或哈希白名单控制可信内联脚本
若业务中确需少量内联脚本(如初始化数据),不能靠 'unsafe-inline',而应采用白名单机制:
- 服务端为每个响应生成唯一
nonce(如nonce-AbC123),并在 HTTP 头中声明:Content-Security-Policy: script-src 'self' 'nonce-AbC123'; - 对应 HTML 中的脚本必须带该属性:
<script nonce="AbC123">initApp();</script> - 或对短小确定的内联脚本计算 SHA256 哈希,写入策略:
script-src 'sha256-abc...xyz';
限制 DOM 写入源头,堵住 innerHTML / document.write 入口
很多 DOM 型 XSS 来自 JavaScript 动态写入未过滤内容,例如 el.innerHTML = location.hash。CSP 本身不拦截 DOM API 调用,但可通过组合策略大幅压缩攻击面:
- 配合
default-src 'none';关闭所有默认资源加载,再逐项放开必需项(如img-src *) - 设置
object-src 'none'; base-uri 'none';防止通过<object>或<base>间接执行脚本 - 启用
report-uri或report-to收集违规日志,快速发现哪些 DOM 操作触发了 CSP 拦截,定位问题代码
补充关键防护动作(非 CSP 但必须同步做)
CSP 是防线,不是万能解药。生产环境必须搭配以下操作:
- 前端读取 URL 参数、hash、localStorage 等用户可控源时,一律先做 HTML 实体转义,再写入 DOM;避免直接拼接字符串到
innerHTML - 禁用
eval()、setTimeout(string)、setInterval(string)、Function(string)等动态执行函数 - 服务端返回 HTML 时,确保所有用户输入都经过上下文敏感的输出编码(如 HTML 上下文用

















