首页 / Tauri 2 入门教程 / 内容安全策略(CSP)

Tauri 2 入门教程

内容安全策略(CSP)

本教程共 48 篇 · 第 40 篇 · 更新于 2026-08-09 · 约 10 分钟阅读

TauriTauri 2 入门教程CSP内容安全策略安全nonceWebViewXSS 防护

本节目标:读完你能看懂 CSP 各条指令的含义,在 tauri.conf.json 里写出合理的 CSP 配置,并理解 Tauri 自动注入 nonce 和 hash 的机制。

如果你的前端页面被注入了一段恶意脚本(XSS 攻击),这段脚本能做什么?没有 CSP 的话,它能发网络请求、能加载外部资源、能执行任意 JS。CSP(Content Security Policy,内容安全策略)就是给 WebView 画一道框——哪些来源的脚本可以执行、哪些来源的图片可以加载、能连哪些网络地址,都由 CSP 说了算。

CSP 是什么

CSP 本来是 Web 标准里的安全机制,浏览器用它来限制页面能加载哪些资源。Tauri 的 WebView 也支持 CSP,而且 Tauri 在编译时会自动帮你做一部分工作——本地脚本会被计算哈希,外部脚本会被分配 nonce(一次性随机数),让合法脚本正常加载、非法脚本被挡掉。

CSP 在 Tauri 中不是默认开启的。你需要在 tauri.conf.json 里显式配置,它才生效。

在 tauri.conf.json 中配置 CSP

CSP 配置写在 app.security.csp 字段里。可以写成字符串,也可以写成对象(按指令分别设置):

// 字符串形式
{
  "app": {
    "security": {
      "csp": "default-src 'self'; connect-src ipc: http://ipc.localhost"
    }
  }
}
// 对象形式
{
  "app": {
    "security": {
      "csp": {
        "default-src": "'self' customprotocol: asset:",
        "connect-src": "ipc: http://ipc.localhost",
        "font-src": ["https://fonts.gstatic.com"],
        "img-src": "'self' asset: http://asset.localhost blob: data:",
        "style-src": "'unsafe-inline' 'self' https://fonts.googleapis.com"
      }
    }
  }
}

两种写法效果一样,对象形式更易读,适合多指令的场景。

常用 CSP 指令解读

CSP 由多条指令组成,每条指令控制一类资源的加载策略。以下是 Tauri 应用中最常用的几条:

default-src 是兜底指令——其他指令没明确配置的资源类型,都走 default-src 的规则。'self' 表示只允许加载同源资源(即应用自带的文件)。这是最基础的一道防线。

connect-src 控制能连哪些网络地址。Tauri 应用里必须包含 ipc: http://ipc.localhost,否则前端无法通过 IPC 和后端通信——这是 Tauri 特有的。

script-src 控制能执行哪些脚本。Tauri 会在编译时自动给本地脚本加 hash、给外部脚本加 nonce,你一般不需要手动配。但如果你的前端用了 WebAssembly,要加上 'wasm-unsafe-eval'

style-src 控制能加载哪些样式。如果用了内联样式(很多 UI 框架会注入),需要 'unsafe-inline'

img-src 控制能加载哪些图片。data: 允许 base64 图片,blob: 允许 Blob URL 图片。

font-src 控制能加载哪些字体文件。如果用了 Google Fonts,需要允许 https://fonts.gstatic.com

Note

'self' 中的引号是 CSP 语法的一部分,不是字符串引号。在 JSON 里写 'self' 时,整个值是字符串 "default-src 'self'"'self' 是其中的一个 source 关键字。

nonce 与 hash 自动注入

你可能会想:我配了 script-src 'self',那内联的 <script> 标签不就被拦了吗?没错,CSP 默认不允许内联脚本。但 Tauri 帮你解决了这个问题。

在编译时,Tauri 会扫描 HTML 中的内联脚本,计算它们的 SHA-256 哈希值,然后自动追加到 CSP 的 script-src 里。对于外部引用的脚本和样式文件,Tauri 会生成一个随机的 nonce(number used once),附加到资源标签上,同时在 CSP 中允许这个 nonce。

你不需要手动做任何事——Tauri 在构建时全自动处理。你配的 CSP 是「你自己应用的额外规则」,Tauri 的自动注入是在你的配置基础上「追加」的。

编译后的 HTML 里,你可能会看到类似这样的结果:

content-security-policy: default-src 'self'; connect-src ipc: http://ipc.localhost; script-src 'self' 'sha256-Wjjrs6qinmnr+tOry8x8PPwI77eGpUFR3EEGZktjJNs='

那个 sha256-... 就是 Tauri 自动算出来的内联脚本哈希。

一个推荐的 CSP 模板

对于大多数 Tauri 应用,以下 CSP 配置是一个比较合理的起点:

{
  "app": {
    "security": {
      "csp": {
        "default-src": "'self'",
        "connect-src": "ipc: http://ipc.localhost",
        "img-src": "'self' asset: http://asset.localhost blob: data:",
        "style-src": "'unsafe-inline' 'self'"
      }
    }
  }
}

这个模板做了几件事:

  • default-src 'self':默认只允许加载同源资源
  • connect-src 保留 IPC 通道,前端能和后端通信
  • img-src 允许 Tauri 资源协议、Blob 和 base64 图片
  • style-src 允许内联样式(大多数 UI 框架需要)

如果你的前端用了 WebAssembly,加上 script-src

"script-src": "'self' 'wasm-unsafe-eval'"
Tip

CSP 配置没有「标准答案」,取决于你的应用实际加载了哪些资源。最稳妥的做法是:先配一个严格的 CSP,然后跑应用看控制台报什么 CSP 违规错误,根据错误逐步放开需要的资源来源。这叫「白名单模式」——从最紧开始放,而不是从最松开始收。

避免加载远程内容

CSP 最重要的一条实践:尽量不要从远程 CDN 加载脚本

// 不推荐:依赖远程 CDN
"script-src": "'self' https://cdn.jsdelivr.net"

// 推荐:把资源下载到本地
"script-src": "'self'"

原因很直接——CDN 被入侵或域名过期被抢注后,攻击者可以替换你的脚本,这是真实的攻击向量。把第三方库下载到本地、打包进应用,是更安全的做法。

Warning

如果你必须加载远程资源(比如连后端 API),确保走 HTTPS,并在 CSP 中明确指定域名。绝不要用通配符 * 放开所有来源——这等于没配 CSP。

HTTP 安全头

除了 CSP,Tauri 还支持配置其他 HTTP 安全响应头。这些头会随 WebView 的响应一起发送:

{
  "app": {
    "security": {
      "headers": {
        "Cross-Origin-Opener-Policy": "same-origin",
        "Cross-Origin-Embedder-Policy": "require-corp",
        "X-Content-Type-Options": "nosniff"
      },
      "csp": "default-src 'self'; connect-src ipc: http://ipc.localhost"
    }
  }
}

注意 CSP 不放在 headers 里,它有独立的 csp 字段。headers 里支持的头部名称是有限制的,包括 CORS 相关头、COOP、COEP、CORP 等,但不包含 CSP。

Note

开发环境下,前端框架(Vite、Angular 等)的 dev server 会注入自己的 HTTP 头。Tauri 只能在构建产物中注入头,不能注入到 dev server 的响应里。所以某些安全头在开发时可能不生效,构建后才会正常工作。如果需要开发时也生效,要同时在前端框架的配置里加对应的头。

小结

CSP 是 Tauri 安全模型的「前端防线」,限制 WebView 能加载和执行哪些资源。在 tauri.conf.jsonapp.security.csp 中配置,支持字符串和对象两种写法。Tauri 在编译时自动为内联脚本计算 hash、为外部脚本生成 nonce,追加到 CSP 中——你只需配置应用特有的规则。推荐从严格配置开始,按需逐步放开。最关键的实践是避免加载远程 CDN 脚本,把第三方资源下载到本地打包。此外还可以通过 app.security.headers 配置 COOP、COEP 等安全头,和 CSP 一起构成多层防护。