CSP 不阻止 querySelector 调用,而是阻止恶意脚本加载执行;需禁用 'unsafe-inline' 和 'unsafe-eval',严格限制 script-src 白名单,启用 strict-dynamic 与 report-only 模式灰度验证,并配合前端加固措施。

禁用内联脚本和 eval 类危险行为
绝大多数基于 `querySelector` 的动态注入攻击,都藏在内联 `<script>`、`onclick=` 属性或 `setTimeout("...")` 字符串中。CSP 必须显式禁止这些载体:</script>
- 去掉 `'unsafe-inline'` 和 `'unsafe-eval'` —— 它们是 XSS 的快捷通道
- 把所有内联 JS 拆成外部文件,或改用 `nonce`/`hash` 白名单方式授权
- 重写 `setTimeout("alert(1)")` 为 `setTimeout(() => alert(1), 10)`,避免字符串执行
严格控制 script-src 白名单
只允许加载你完全信任的脚本源,包括你自己域名和明确审核过的 CDN:
- 用 `'self'` 限定同源脚本(注意:`'self'` 不包含子域,需显式加 `https://cdn.example.com`)
- 第三方库如 jQuery、Lodash 若必须用 CDN,只写具体域名,禁用通配符 `*`
- 启用 `strict-dynamic`(配合 nonce 或 hash):一旦可信脚本加载,它动态创建的子脚本也自动被信任,避免白名单爆炸式增长
启用 report-only 模式做灰度验证
上线前别直接强制拦截,先用 `Content-Security-Policy-Report-Only` 头收集真实违规:
- 搭配 `report-uri` 或 `report-to`,把浏览器上报的违规详情(含触发脚本 URL、行号、内联代码片段)接入日志系统
- 重点检查是否误拦了合法的 `querySelector` 使用(比如框架内部逻辑),再针对性加 nonce 或 hash
- 确认连续 3 天无高危违规(如 `eval` 调用、未授权内联脚本)后再切到正式 `Content-Security-Policy` 头
配合前端加固,堵住剩余入口
CSP 是纵深防御的一环,还需同步收紧前端执行环境:
- 禁用 `innerHTML` 直接写入用户数据,改用 `textContent` 或安全模板引擎(如 Handlebars with auto-escaping)
- 对用户可控的 DOM 操作(如富文本编辑器输出)额外过一遍 HTML sanitizer(如 DOMPurify)
- 敏感操作(如支付、删除)要求二次确认,不依赖纯前端 DOM 隐藏/显示判断权限

















