mcpField
C
configuring-tauri-csp

configuring-tauri-csp

github.com/dchuk安全36163 次安装40 周前更新
代码仓库

关于 configuring-tauri-csp

面向开发者的技能,介绍如何为 Tauri v2 桌面应用配置内容安全策略。涵盖指令、配置格式、框架相关设置及资源限制故障排查。

主要功能

  1. 01在 Tauri 设置中配置 CSP
  2. 02设置脚本与资源的策略指令
  3. 03选择对象、数组或字符串格式
  4. 04按前端框架调整策略
  5. 05排查资源拦截与 IPC 问题

适用场景

  1. 01限制桌面应用的外部连接
  2. 02在 CSP 下允许 WebAssembly 脚本
  3. 03诊断被策略拦截的资源

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dchuk/claude-code-tauri-skills --skill configuring-tauri-csp

安装后在 Claude Code 中输入/configuring-tauri-csp确认已加载。

详细介绍

Tauri 内容安全策略(CSP)配置

本技能介绍如何为 Tauri v2 桌面应用配置内容安全策略。

CSP 对 Tauri 的重要性

CSP 是一种安全机制,可缓解 Tauri 应用中的常见 Web 漏洞:

  1. 防止 XSS:限制可执行的脚本,阻止注入的恶意代码
  2. 资源控制:限制 WebView 可从哪些位置加载资源(脚本、样式、图片、字体)
  3. 信任边界:加强前端 WebView 与后端 Rust 代码之间的隔离
  4. 缩小攻击面:防止未授权的网络连接和资源加载

Tauri 采用信任边界模型,前端代码通过定义明确的 IPC 层,只能有限地访问系统资源。CSP 会在前端信任区域内增加一层额外保护。

Tauri 如何实现 CSP

Tauri 采用两部分保护策略:

  1. 本地脚本:在编译时通过加密哈希进行保护
  2. 样式和外部脚本:使用 nonce 进行验证

Tauri 会在编译期间自动为打包后的代码添加 nonce 和哈希。开发者只需配置应用专用的可信来源。

重要:只有在 Tauri 配置文件中明确配置后,CSP 保护才会启用。

CSP 的默认行为

默认情况下,Tauri 不会应用 CSP。你必须在 tauri.conf.json 的 security 部分中明确配置:

{
  "security": {
    "csp": null
  }
}

当 csp 为 null 或未设置时,不会强制执行内容安全策略。

基本 CSP 配置

最小安全配置
{
  "security": {
    "csp": {
      "default-src": "'self'"
    }
  }
}

此配置会将所有资源限制为仅来自同一源。

推荐配置
{
  "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"
    }
  }
}

Tauri 常用的 CSP 指令

default-src

为未明确指定的所有资源类型设置回退策略。

"default-src": "'self' customprotocol: asset:"

常用值:

  • 'self' - 仅限同一源
  • 'none' - 阻止所有资源
  • customprotocol: - Tauri 自定义协议
  • asset: - Tauri 资源协议
script-src

控制允许执行哪些脚本。

"script-src": "'self'"

对于 WebAssembly 或基于 Rust 的前端(Leptos、Yew、Dioxus):

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

警告:除非绝对必要,否则不要使用 'unsafe-eval'。

style-src

控制样式表来源。

"style-src": "'self' 'unsafe-inline' https://fonts.googleapis.com"

注意:CSS-in-JS 库通常需要 'unsafe-inline',但这会降低安全性。

connect-src

控制 fetch、WebSocket 等允许连接的目标。

"connect-src": "ipc: http://ipc.localhost https://api.example.com"

Tauri 专用:

  • ipc: - 与 Rust 后端进行进程间通信
  • http://ipc.localhost - 备用 IPC 端点
img-src

控制图片加载来源。

"img-src": "'self' asset: http://asset.localhost blob: data:"

常用值:

  • blob: - Blob URL(用于动态创建的图片)
  • data: - Data URL(Base64 编码的图片)
  • asset: - Tauri 资源协议
font-src

控制字体加载来源。

"font-src": "'self' https://fonts.gstatic.com"
frame-src

控制 iframe 来源。

"frame-src": "'none'"

除非有特定需求,否则建议阻止所有框架。

object-src

控制插件内容(Flash、Java 等)。

"object-src": "'none'"

对于现代应用,始终将其设置为 'none'。

配置格式选项

对象格式(推荐)
{
  "security": {
    "csp": {
      "default-src": "'self'",
      "script-src": "'self' 'wasm-unsafe-eval'",
      "style-src": "'self' 'unsafe-inline'"
    }
  }
}
多个来源的数组格式
{
  "security": {
    "csp": {
      "font-src": ["'self'", "https://fonts.gstatic.com", "https://fonts.googleapis.com"]
    }
  }
}
字符串格式
{
  "security": {
    "csp": "default-src 'self'; script-src 'self'"
  }
}

特定框架的配置

React/Vue/Svelte(标准 JS 框架)
{
  "security": {
    "csp": {
      "default-src": "'self'",
      "script-src": "'self'",
      "style-src": "'self' 'unsafe-inline'",
      "img-src": "'self' data: blob:",
      "font-src": "'self'",
      "connect-src": "ipc: http://ipc.localhost"
    }
  }
}
Leptos/Yew/Dioxus(Rust/WASM 框架)
{
  "security": {
    "csp": {
      "default-src": "'self'",
      "script-src": "'self' 'wasm-unsafe-eval'",
      "style-src": "'self' 'unsafe-inline'",
      "img-src": "'self' data: blob:",
      "font-src": "'self'",
      "connect-src": "ipc: http://ipc.localhost"
    }
  }
}
使用外部 API
{
  "security": {
    "csp": {
      "default-src": "'self'",
      "script-src": "'self'",
      "connect-src": "ipc: http://ipc.localhost https://api.example.com wss://ws.example.com",
      "img-src": "'self' https://cdn.example.com"
    }
  }
}

安全最佳实践

1. 避免远程脚本

生产环境中绝不要从 CDN 加载脚本:

// AVOID - introduces attack vector
"script-src": "'self' https://cdn.jsdelivr.net"

// PREFERRED - bundle all dependencies
"script-src": "'self'"
2. 尽量减少 unsafe-inline

仅在框架要求时使用 'unsafe-inline':

// More secure
"style-src": "'self'"

// Less secure but sometimes necessary
"style-src": "'self' 'unsafe-inline'"
3. 使用严格的默认设置

先采用严格设置,再根据需要添加权限:

{
  "security": {
    "csp": {
      "default-src": "'none'",
      "script-src": "'self'",
      "style-src": "'self'",
      "img-src": "'self'",
      "font-src": "'self'",
      "connect-src": "ipc: http://ipc.localhost"
    }
  }
}
4. 阻止危险功能

始终阻止未使用的危险功能:

{
  "security": {
    "csp": {
      "object-src": "'none'",
      "base-uri": "'self'",
      "form-action": "'self'"
    }
  }
}

高级配置

禁用 CSP 修改

如果你需要完全控制 CSP(不推荐):

{
  "security": {
    "csp": {
      "default-src": "'self'"
    },
    "dangerousDisableAssetCspModification": true
  }
}

警告:这会禁用 Tauri 自动注入 nonce 和哈希。

冻结原型

冻结 JavaScript 原型以提供额外的 XSS 保护:

{
  "security": {
    "csp": {
      "default-src": "'self'"
    },
    "freezePrototype": true
  }
}

故障排除

CSP 阻止资源

检查浏览器开发者工具控制台中的 CSP 违规消息。这些消息会指出哪个指令阻止了资源。

错误示例:

Refused to load the script 'https://example.com/script.js' because it violates the following Content Security Policy directive: "script-src 'self'"

解决方案:将域名添加到相应的指令中:

"script-src": "'self' https://example.com"
WebAssembly 未加载

将 'wasm-unsafe-eval' 添加到 script-src:

"script-src": "'self' 'wasm-unsafe-eval'"
内联样式不起作用

对于 CSS-in-JS 库,将 'unsafe-inline' 添加到 style-src:

"style-src": "'self' 'unsafe-inline'"
IPC 不起作用

确保 connect-src 包含 Tauri IPC 端点:

"connect-src": "ipc: http://ipc.localhost"

完整配置示例

{
  "productName": "my-tauri-app",
  "version": "1.0.0",
  "security": {
    "csp": {
      "default-src": "'self' customprotocol: asset:",
      "script-src": "'self'",
      "style-src": "'self' 'unsafe-inline'",
      "img-src": "'self' asset: http://asset.localhost blob: data:",
      "font-src": "'self'",
      "connect-src": "ipc: http://ipc.localhost",
      "object-src": "'none'",
      "base-uri": "'self'",
      "form-action": "'self'",
      "frame-ancestors": "'none'"
    },
    "freezePrototype": true
  }
}

参考资料

评论

支持 Markdown