人人都会AI编程

常见 CSP 配置错误与规避

更新时间:2026-07-11

在 Tauri 中,内容安全策略(CSP)是加固前端安全的核心防线,尤其在 WebView 环境中,CSP 几乎是你抵御 XSS 和数据注入攻击的唯一内置屏障。然而,实际开发中经常看到一些配置错误,不仅让 CSP 形同虚设,还可能导致应用功能异常。


1. 默认放开所有来源:default-src *

错误现象
为了方便,直接将 CSP 设为 default-src default-src 'unsafe-inline' 'unsafe-eval' 。这等于完全关闭了 CSP 的保护,任何内联脚本、远程资源都可以执行。

风险和后果
一旦前端页面的任何一处存在 DOM XSS 漏洞,攻击者可以自由加载外部脚本并执行,访问 Tauri 的 IPC 接口(如果你还错误地允许了全部命令),甚至可以调用原生 API 进行恶意操作。

正确做法

  • 永远将 default-src 设置为最小权限,例如 'self'
  • 如果确实需要加载外部资源(如 CDN 字体、图片),单独指定 font-srcimg-src 等指令,限制到具体域名。
  • 内联脚本和样式通常应避免,如果必须使用,使用 'nonce-...''sha256-...' 哈希替代 'unsafe-inline'

2. 忘记添加 'nonce' 导致内联代码完全阻止

错误现象
很多 UI 框架(如 Vue、React)会在 HTML 中内联一小段初始化脚本。如果在 CSP 中只写了 script-src 'self',这些内联脚本会被阻止,页面出现空白或报错。

避免方法

  • 尽量将启动逻辑提取到外部 .js 文件中加载。
  • 如果必须内联,在 HTML 的 <script> 标签上添加 nonce 属性,并在 Tauri 配置的 CSP 中写入 script-src 'self' 'nonce-{随机值}'。每次页面加载时 nonce 必须随机生成,且不能重复使用。

3. 混淆开发环境与生产环境的 CSP

错误现象
开发时为了方便,开启了 'unsafe-eval'(Vue 等框架需要 eval 做热重载)和 'unsafe-inline',结果生产版本忘记收紧,直接保留了这些危险配置。

规避策略

  • 使用环境变量区分开发和构建时的 CSP。开发时允许 eval,构建后自动移除。
  • 在打包前利用脚本检查最终 HTML 中的 CSP 标签,确保不包含 unsafe-eval 和不必要的 unsafe-inline
  • Tauri 可以在 tauri.conf.json 中配置 security.csp,这个 CSP 会施加到所有页面,是最后的防线,务必保持收紧。

4. 遗漏了 connect-src,导致 API 请求或 WebSocket 断连

错误现象
设置了严格的 default-src 'self',但前端需要通过 fetch 调用本地 Rust 命令(实质上是 IPC 请求)或连接某些远程接口。由于未设置 connect-src,这些请求会被 CSP 阻挡,控制台报错 Refused to connect

解决方法

  • 明确添加 connect-src 'self' https://your-api.com,将你所有需要请求的源加进来。
  • 注意 Tauri 的 IPC 调用使用的是 tauri://localhost 或自定义协议,需要添加到 CSP 中:connect-src 'self' tauri: https://your-api.com

5. 错误的 frame-src 导致 iframe 内容无法加载

错误现象
应用中嵌入了一个 iframe 显示外部网页,但 CSP 默认没有 frame-src 指令,浏览器会回退使用 default-src,导致 iframe 资源被阻止。

修复

  • 显式设置 frame-src https://trusted.site,仅允许你信任的源嵌入。避免使用通配符。

6. 依赖 HTTP 头 CSP 而忽略 meta 标签

在 Tauri 中,前端页面通常是通过本地文件或自定义协议加载的,服务器响应头可能不可控。很多开发者会忘记在 HTML 中使用 <meta http-equiv="Content-Security-Policy" content="..."> 来设置 CSP,导致策略未生效。

最佳实践

  • index.html 中始终放置一个最小化的 CSP meta 标签。
  • Tauri 的 tauri.conf.json 中的 security.csp 会覆盖 HTML 中的 meta,可以用来设定全局策略,但也要确保 HTML 有基本策略以防止配置失误。

7. 使用 'strict-dynamic' 时的错误理解

'strict-dynamic' 可以动态信任由已受信脚本加载的其他脚本,但如果不了解它的规则,可能会误以为它自动放行所有脚本。实际上 'strict-dynamic' 会忽略基于 URL 的主机白名单,只信任通过 nonce 或哈希验证的脚本所加载的子脚本。如果同时使用了 'unsafe-inline''strict-dynamic' 会被忽略。

使用建议
仅在确实需要动态脚本加载且已全面使用 nonce 的场景下使用。大多数 Tauri 应用不需要它。


总结:CSP 配置没有“一刀切”的方案,但遵循“最小权限、精确来源、不去生产环境留后门”的原则,可以让你既保持安全又不影响功能。每次修改前端或添加新依赖后,都应在浏览器 DevTools 的 Security 面板检查是否有 CSP 违规报告,及时修正。