From 067b3764d2cfdb87773255cbd62a028d2a806da6 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 11 Jul 2025 17:46:27 +0800 Subject: [PATCH] fix --- docs/mixvideo-security-optimization.md | 276 +++++++++++++ docs/tauri-security-config-guide.md | 520 +++++++++++++++++++++++++ src-tauri/tauri.conf.json | 4 +- 3 files changed, 798 insertions(+), 2 deletions(-) create mode 100644 docs/mixvideo-security-optimization.md create mode 100644 docs/tauri-security-config-guide.md diff --git a/docs/mixvideo-security-optimization.md b/docs/mixvideo-security-optimization.md new file mode 100644 index 0000000..d19e041 --- /dev/null +++ b/docs/mixvideo-security-optimization.md @@ -0,0 +1,276 @@ +# MixVideo 安全配置优化建议 + +基于当前项目配置的安全优化方案 + +## 📊 当前配置分析 + +### 🔍 现有配置 +```json +{ + "security": { + "csp": "default-src 'self' ipc: http://ipc.localhost; img-src 'self' asset: http://asset.localhost data:; media-src 'self' asset: http://asset.localhost; video-src 'self' asset: http://asset.localhost; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'", + "assetProtocol": { + "enable": true, + "scope": ["**"] + } + } +} +``` + +### ⚠️ 安全风险评估 + +| 配置项 | 风险级别 | 问题描述 | 影响 | +|--------|----------|----------|------| +| `scope: ["**"]` | 🔴 高风险 | 允许访问所有文件系统 | 可能泄露敏感文件 | +| `'unsafe-inline'` | 🟡 中风险 | 允许内联脚本和样式 | XSS 攻击风险 | +| 缺少 `devCsp` | 🟡 中风险 | 开发和生产使用相同策略 | 开发体验受限 | +| 缺少 `freezePrototype` | 🟢 低风险 | 未防护原型污染 | 潜在安全隐患 | + +--- + +## 🎯 优化建议 + +### 1. 立即优化 (高优先级) + +#### AssetProtocol Scope 限制 +```json +{ + "assetProtocol": { + "enable": true, + "scope": [ + "$HOME/.mixvideo/**", + "$APPDATA/mixvideo/**", + "$TEMP/mixvideo/**", + "$HOME/Videos/**", + "$HOME/Movies/**", + "$DESKTOP/**", + "$DOCUMENT/**" + ] + } +} +``` + +**优势**: +- ✅ 限制文件访问范围 +- ✅ 防止访问系统敏感文件 +- ✅ 保持功能完整性 + +### 2. CSP 策略优化 + +#### 推荐配置 +```json +{ + "security": { + "csp": { + "default-src": ["'self'"], + "connect-src": ["'self'", "ipc:", "http://ipc.localhost"], + "img-src": ["'self'", "asset:", "http://asset.localhost", "data:"], + "media-src": ["'self'", "asset:", "http://asset.localhost"], + "video-src": ["'self'", "asset:", "http://asset.localhost"], + "script-src": ["'self'", "'unsafe-inline'"], + "style-src": ["'self'", "'unsafe-inline'"], + "font-src": ["'self'", "data:"] + }, + "devCsp": { + "default-src": ["'self'", "'unsafe-eval'"], + "connect-src": ["'self'", "ipc:", "http://ipc.localhost", "ws:", "wss:"], + "img-src": ["'self'", "asset:", "http://asset.localhost", "data:"], + "media-src": ["'self'", "asset:", "http://asset.localhost"], + "video-src": ["'self'", "asset:", "http://asset.localhost"], + "script-src": ["'self'", "'unsafe-inline'", "'unsafe-eval'"], + "style-src": ["'self'", "'unsafe-inline'"], + "font-src": ["'self'", "data:"] + } + } +} +``` + +**优势**: +- ✅ 分离开发和生产环境 +- ✅ 支持热重载 (`'unsafe-eval'` 仅开发环境) +- ✅ 支持 WebSocket 连接 (开发环境) + +### 3. 完整优化配置 + +#### 生产就绪配置 +```json +{ + "app": { + "security": { + "csp": { + "default-src": ["'self'"], + "connect-src": ["'self'", "ipc:", "http://ipc.localhost"], + "img-src": ["'self'", "asset:", "http://asset.localhost", "data:"], + "media-src": ["'self'", "asset:", "http://asset.localhost"], + "video-src": ["'self'", "asset:", "http://asset.localhost"], + "script-src": ["'self'", "'unsafe-inline'"], + "style-src": ["'self'", "'unsafe-inline'"], + "font-src": ["'self'", "data:"], + "object-src": ["'none'"], + "base-uri": ["'self'"], + "form-action": ["'self'"] + }, + "devCsp": { + "default-src": ["'self'", "'unsafe-eval'"], + "connect-src": ["'self'", "ipc:", "http://ipc.localhost", "ws://localhost:*", "wss://localhost:*"], + "img-src": ["'self'", "asset:", "http://asset.localhost", "data:"], + "media-src": ["'self'", "asset:", "http://asset.localhost"], + "video-src": ["'self'", "asset:", "http://asset.localhost"], + "script-src": ["'self'", "'unsafe-inline'", "'unsafe-eval'"], + "style-src": ["'self'", "'unsafe-inline'"], + "font-src": ["'self'", "data:"], + "object-src": ["'none'"], + "base-uri": ["'self'"], + "form-action": ["'self'"] + }, + "assetProtocol": { + "enable": true, + "scope": [ + "$HOME/.mixvideo/**", + "$APPDATA/mixvideo/**", + "$LOCALAPPDATA/mixvideo/**", + "$TEMP/mixvideo/**", + "$HOME/Videos/**", + "$HOME/Movies/**", + "$HOME/Pictures/**", + "$DESKTOP/**", + "$DOCUMENT/**", + "$DOWNLOAD/**" + ] + }, + "freezePrototype": true, + "dangerousDisableAssetCspModification": false + } + } +} +``` + +--- + +## 🔄 迁移步骤 + +### 步骤 1: 备份当前配置 +```bash +cp src-tauri/tauri.conf.json src-tauri/tauri.conf.json.backup +``` + +### 步骤 2: 渐进式更新 + +#### 2.1 首先限制 AssetProtocol Scope +```json +{ + "assetProtocol": { + "enable": true, + "scope": [ + "$HOME/.mixvideo/**", + "$APPDATA/mixvideo/**", + "$TEMP/mixvideo/**", + "$HOME/Videos/**", + "$HOME/Movies/**" + ] + } +} +``` + +#### 2.2 测试基本功能 +- 视频导入 +- 视频播放 +- 文件保存 + +#### 2.3 添加开发环境 CSP +```json +{ + "devCsp": { + "default-src": ["'self'", "'unsafe-eval'"], + "connect-src": ["'self'", "ipc:", "http://ipc.localhost", "ws:", "wss:"], + "img-src": ["'self'", "asset:", "http://asset.localhost", "data:"], + "media-src": ["'self'", "asset:", "http://asset.localhost"], + "video-src": ["'self'", "asset:", "http://asset.localhost"], + "script-src": ["'self'", "'unsafe-inline'", "'unsafe-eval'"], + "style-src": ["'self'", "'unsafe-inline'"], + "font-src": ["'self'", "data:"] + } +} +``` + +#### 2.4 转换生产 CSP 为对象格式 +```json +{ + "csp": { + "default-src": ["'self'"], + "connect-src": ["'self'", "ipc:", "http://ipc.localhost"], + "img-src": ["'self'", "asset:", "http://asset.localhost", "data:"], + "media-src": ["'self'", "asset:", "http://asset.localhost"], + "video-src": ["'self'", "asset:", "http://asset.localhost"], + "script-src": ["'self'", "'unsafe-inline'"], + "style-src": ["'self'", "'unsafe-inline'"], + "font-src": ["'self'", "data:"] + } +} +``` + +### 步骤 3: 验证和测试 + +#### 3.1 功能测试清单 +- [ ] 视频文件导入 +- [ ] 视频播放和预览 +- [ ] 图片资源显示 +- [ ] 模板导入和使用 +- [ ] 项目保存和加载 +- [ ] Python 脚本执行 +- [ ] 开发热重载 + +#### 3.2 安全测试 +- [ ] 尝试访问系统敏感文件 +- [ ] 检查 CSP 违规报告 +- [ ] 验证文件访问权限 + +--- + +## 🚨 注意事项 + +### 1. Windows 路径兼容性 +确保 scope 配置支持 Windows 路径: +```json +{ + "scope": [ + "$APPDATA/mixvideo/**", + "$LOCALAPPDATA/mixvideo/**", + "C:\\Users\\*\\Videos\\**", + "C:\\Users\\*\\Documents\\**" + ] +} +``` + +### 2. 开发环境特殊需求 +- 保留 `'unsafe-eval'` 用于热重载 +- 添加 WebSocket 支持用于开发服务器 +- 允许 localhost 连接 + +### 3. 生产环境安全 +- 移除所有 `unsafe-*` 指令(除非必要) +- 严格限制文件访问范围 +- 启用原型冻结保护 + +--- + +## 📈 预期收益 + +### 安全性提升 +- 🔒 **文件系统保护**: 限制访问范围,防止敏感文件泄露 +- 🛡️ **XSS 防护**: 更严格的 CSP 策略 +- 🔐 **原型污染防护**: 启用 freezePrototype + +### 开发体验 +- 🚀 **热重载支持**: 开发环境允许 eval +- 🔧 **调试友好**: WebSocket 和开发工具支持 +- ⚡ **性能优化**: 更精确的资源加载策略 + +### 维护性 +- 📝 **配置清晰**: 对象格式更易读和维护 +- 🔄 **环境分离**: 开发和生产配置独立 +- 📊 **监控友好**: 更好的 CSP 违规报告 + +--- + +*建议在测试环境中先验证配置,确认功能正常后再应用到生产环境* diff --git a/docs/tauri-security-config-guide.md b/docs/tauri-security-config-guide.md new file mode 100644 index 0000000..790baa5 --- /dev/null +++ b/docs/tauri-security-config-guide.md @@ -0,0 +1,520 @@ +# Tauri 安全配置详细指南 + +基于 Tauri CLI Schema v2.6.2 的完整安全配置说明文档 + +## 📋 目录 + +- [SecurityConfig 安全配置](#securityconfig-安全配置) +- [CSP 内容安全策略](#csp-内容安全策略) +- [AssetProtocol 资源协议](#assetprotocol-资源协议) +- [最佳实践建议](#最佳实践建议) +- [常见配置示例](#常见配置示例) + +--- + +## SecurityConfig 安全配置 + +### 📖 概述 +`SecurityConfig` 是 Tauri 应用程序的核心安全配置对象,控制着应用的安全策略、内容安全策略(CSP)、资源访问协议等关键安全特性。 + +### 🔧 配置结构 + +```json +{ + "app": { + "security": { + "csp": "...", + "devCsp": "...", + "assetProtocol": {...}, + "dangerousDisableAssetCspModification": false, + "freezePrototype": false, + "pattern": {...}, + "capabilities": [...], + "headers": {...} + } + } +} +``` + +--- + +## CSP 内容安全策略 + +### 📖 定义 +Content Security Policy (CSP) 是一个重要的安全层,用于检测和减轻某些类型的攻击,包括跨站脚本 (XSS) 和数据注入攻击。 + +### 🔧 配置选项 + +#### 1. `csp` - 生产环境CSP +```json +{ + "csp": "default-src 'self'; script-src 'self' 'unsafe-inline'" +} +``` + +**类型**: `string | object | null` +**默认值**: `null` +**用途**: +- 定义生产环境下的内容安全策略 +- 如果未设置 `devCsp`,开发环境也会使用此配置 +- 控制哪些资源可以被加载和执行 + +#### 2. `devCsp` - 开发环境CSP +```json +{ + "devCsp": "default-src 'self' 'unsafe-eval'; script-src 'self' 'unsafe-inline'" +} +``` + +**类型**: `string | object | null` +**默认值**: `null` +**用途**: +- 专门用于开发环境的CSP配置 +- 通常比生产环境更宽松,允许热重载等开发工具 + +### 📝 CSP 指令说明 + +#### 字符串格式 +```json +{ + "csp": "default-src 'self'; img-src 'self' data: asset: http://asset.localhost; media-src 'self' asset: http://asset.localhost" +} +``` + +#### 对象格式 +```json +{ + "csp": { + "default-src": ["'self'"], + "img-src": ["'self'", "data:", "asset:", "http://asset.localhost"], + "media-src": ["'self'", "asset:", "http://asset.localhost"], + "script-src": ["'self'", "'unsafe-inline'"], + "style-src": ["'self'", "'unsafe-inline'"] + } +} +``` + +### 🎯 常用CSP指令 + +| 指令 | 说明 | 示例值 | +|------|------|--------| +| `default-src` | 默认源策略 | `'self'` | +| `script-src` | JavaScript源 | `'self' 'unsafe-inline'` | +| `style-src` | CSS样式源 | `'self' 'unsafe-inline'` | +| `img-src` | 图片源 | `'self' data: asset:` | +| `media-src` | 媒体源 | `'self' asset:` | +| `connect-src` | 连接源 | `'self' ipc: http://ipc.localhost` | +| `font-src` | 字体源 | `'self' data:` | + +--- + +## AssetProtocol 资源协议 + +### 📖 定义 +AssetProtocol 配置控制 Tauri 的自定义资源协议,允许前端安全地访问本地文件系统资源。 + +### 🔧 配置结构 + +```json +{ + "assetProtocol": { + "enable": true, + "scope": ["**"] + } +} +``` + +#### 1. `enable` - 启用资源协议 +**类型**: `boolean` +**默认值**: `false` +**用途**: +- 控制是否启用 `asset://` 协议 +- 启用后可以通过 `convertFileSrc()` 访问本地文件 + +#### 2. `scope` - 访问范围 +**类型**: `string[]` +**默认值**: `[]` +**用途**: +- 定义资源协议可以访问的文件路径范围 +- 使用 glob 模式匹配路径 +- 空数组表示禁止访问任何文件 + +### 📝 Scope 配置示例 + +#### 允许访问所有文件 (⚠️ 不推荐) +```json +{ + "scope": ["**"] +} +``` + +#### 限制访问特定目录 +```json +{ + "scope": [ + "$APPDATA/myapp/**", + "$RESOURCE/**", + "/Users/*/Documents/myapp/**" + ] +} +``` + +#### 使用环境变量 +```json +{ + "scope": [ + "$HOME/.myapp/**", + "$TEMP/myapp-cache/**" + ] +} +``` + +--- + +## 高级安全配置 + +### 1. `dangerousDisableAssetCspModification` + +**类型**: `boolean | string[]` +**默认值**: `false` +**用途**: 禁用 Tauri 的 CSP 自动注入 + +```json +{ + "dangerousDisableAssetCspModification": false +} +``` + +**⚠️ 警告**: 只有在完全理解安全影响时才禁用此功能 + +#### 禁用所有CSP修改 +```json +{ + "dangerousDisableAssetCspModification": true +} +``` + +#### 禁用特定指令的修改 +```json +{ + "dangerousDisableAssetCspModification": ["script-src", "style-src"] +} +``` + +### 2. `freezePrototype` + +**类型**: `boolean` +**默认值**: `false` +**用途**: 冻结 `Object.prototype` 以防止原型污染攻击 + +```json +{ + "freezePrototype": true +} +``` + +### 3. `pattern` - 安全模式 + +**类型**: `object` +**用途**: 定义应用的安全模式 + +#### Brownfield 模式 (默认) +```json +{ + "pattern": { + "use": "brownfield" + } +} +``` + +#### Isolation 模式 (推荐) +```json +{ + "pattern": { + "use": "isolation", + "options": { + "dir": "../dist-isolation" + } + } +} +``` + +--- + +## 最佳实践建议 + +### 🔒 安全级别配置 + +#### 高安全级别 (推荐生产环境) +```json +{ + "security": { + "csp": "default-src 'self'; img-src 'self' asset: data:; media-src 'self' asset:; script-src 'self'; style-src 'self' 'unsafe-inline'", + "assetProtocol": { + "enable": true, + "scope": ["$APPDATA/myapp/**", "$RESOURCE/**"] + }, + "freezePrototype": true, + "pattern": { + "use": "isolation", + "options": { + "dir": "../dist-isolation" + } + } + } +} +``` + +#### 中等安全级别 (开发友好) +```json +{ + "security": { + "csp": "default-src 'self'; img-src 'self' asset: data: http://asset.localhost; media-src 'self' asset: http://asset.localhost; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'", + "devCsp": "default-src 'self' 'unsafe-eval'; img-src 'self' asset: data: http://asset.localhost; media-src 'self' asset: http://asset.localhost; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'", + "assetProtocol": { + "enable": true, + "scope": ["**"] + }, + "freezePrototype": false + } +} +``` + +### 🎯 针对不同场景的配置 + +#### 媒体应用 (视频/音频) +```json +{ + "security": { + "csp": { + "default-src": ["'self'"], + "img-src": ["'self'", "asset:", "data:", "http://asset.localhost"], + "media-src": ["'self'", "asset:", "http://asset.localhost"], + "video-src": ["'self'", "asset:", "http://asset.localhost"], + "script-src": ["'self'", "'unsafe-inline'"], + "style-src": ["'self'", "'unsafe-inline'"], + "connect-src": ["'self'", "ipc:", "http://ipc.localhost"] + }, + "assetProtocol": { + "enable": true, + "scope": ["$HOME/Videos/**", "$HOME/Music/**", "$APPDATA/myapp/**"] + } + } +} +``` + +#### 文件管理应用 +```json +{ + "security": { + "csp": "default-src 'self'; img-src 'self' asset: data: http://asset.localhost; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; connect-src 'self' ipc: http://ipc.localhost", + "assetProtocol": { + "enable": true, + "scope": ["$HOME/**", "$DESKTOP/**", "$DOCUMENT/**"] + } + } +} +``` + +--- + +## 🚨 安全注意事项 + +### 1. CSP 配置 +- ❌ 避免使用 `'unsafe-eval'` 在生产环境 +- ❌ 谨慎使用 `'unsafe-inline'` +- ✅ 优先使用 nonce 或 hash 值 +- ✅ 定期审查和更新 CSP 策略 + +### 2. AssetProtocol 配置 +- ❌ 避免使用 `["**"]` 作为 scope +- ✅ 限制访问范围到必要的目录 +- ✅ 使用环境变量定义路径 +- ✅ 定期审查文件访问权限 + +### 3. 开发 vs 生产 +- 开发环境可以适当放宽限制 +- 生产环境必须严格控制安全策略 +- 使用 `devCsp` 区分开发和生产配置 + +--- + +## 🔧 故障排除指南 + +### 常见CSP错误及解决方案 + +#### 1. 视频/音频无法播放 +**错误**: `Refused to load media from 'asset://...' because it violates CSP` + +**解决方案**: +```json +{ + "csp": { + "media-src": ["'self'", "asset:", "http://asset.localhost"], + "video-src": ["'self'", "asset:", "http://asset.localhost"] + } +} +``` + +#### 2. 图片无法显示 +**错误**: `Refused to load image from 'asset://...' because it violates CSP` + +**解决方案**: +```json +{ + "csp": { + "img-src": ["'self'", "asset:", "data:", "http://asset.localhost"] + } +} +``` + +#### 3. 内联样式被阻止 +**错误**: `Refused to apply inline style because it violates CSP` + +**解决方案**: +```json +{ + "csp": { + "style-src": ["'self'", "'unsafe-inline'"] + } +} +``` + +### AssetProtocol 故障排除 + +#### 1. 文件访问被拒绝 +**错误**: `Asset protocol access denied` + +**检查项目**: +- 确认 `assetProtocol.enable` 为 `true` +- 检查文件路径是否在 `scope` 范围内 +- 验证文件是否存在且有读取权限 + +#### 2. Windows 路径问题 +**问题**: Windows 绝对路径无法访问 + +**解决方案**: +```json +{ + "assetProtocol": { + "enable": true, + "scope": [ + "C:\\Users\\**", + "$APPDATA\\**", + "$LOCALAPPDATA\\**" + ] + } +} +``` + +--- + +## 📊 配置验证工具 + +### 1. CSP 验证 +使用浏览器开发者工具检查 CSP 违规: +```javascript +// 在控制台中检查 CSP 策略 +console.log(document.querySelector('meta[http-equiv="Content-Security-Policy"]').content); +``` + +### 2. AssetProtocol 测试 +```javascript +// 测试资源协议是否工作 +import { convertFileSrc } from '@tauri-apps/api/core'; + +const testPath = '/path/to/test/file.txt'; +const assetUrl = convertFileSrc(testPath); +console.log('Asset URL:', assetUrl); + +// 测试文件访问 +fetch(assetUrl) + .then(response => response.text()) + .then(data => console.log('File content:', data)) + .catch(error => console.error('Access denied:', error)); +``` + +--- + +## 🎯 完整配置示例 + +### 视频编辑应用配置 +```json +{ + "app": { + "security": { + "csp": { + "default-src": ["'self'"], + "img-src": ["'self'", "asset:", "data:", "http://asset.localhost"], + "media-src": ["'self'", "asset:", "http://asset.localhost"], + "video-src": ["'self'", "asset:", "http://asset.localhost"], + "script-src": ["'self'", "'unsafe-inline'"], + "style-src": ["'self'", "'unsafe-inline'"], + "connect-src": ["'self'", "ipc:", "http://ipc.localhost"], + "font-src": ["'self'", "data:"] + }, + "devCsp": { + "default-src": ["'self'", "'unsafe-eval'"], + "img-src": ["'self'", "asset:", "data:", "http://asset.localhost"], + "media-src": ["'self'", "asset:", "http://asset.localhost"], + "video-src": ["'self'", "asset:", "http://asset.localhost"], + "script-src": ["'self'", "'unsafe-inline'", "'unsafe-eval'"], + "style-src": ["'self'", "'unsafe-inline'"], + "connect-src": ["'self'", "ipc:", "http://ipc.localhost", "ws:", "wss:"], + "font-src": ["'self'", "data:"] + }, + "assetProtocol": { + "enable": true, + "scope": [ + "$HOME/Videos/**", + "$HOME/Movies/**", + "$DESKTOP/**", + "$DOCUMENT/**", + "$APPDATA/mixvideo/**", + "$TEMP/mixvideo/**" + ] + }, + "freezePrototype": false, + "dangerousDisableAssetCspModification": false + } + } +} +``` + +### 文件管理器配置 +```json +{ + "app": { + "security": { + "csp": "default-src 'self'; img-src 'self' asset: data: http://asset.localhost; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; connect-src 'self' ipc: http://ipc.localhost", + "assetProtocol": { + "enable": true, + "scope": [ + "$HOME/**", + "$DESKTOP/**", + "$DOCUMENT/**", + "$DOWNLOAD/**", + "C:\\**", + "/Users/**", + "/home/**" + ] + }, + "freezePrototype": true + } + } +} +``` + +--- + +## 📚 参考资源 + +- [Tauri 官方安全文档](https://v2.tauri.app/security/) +- [MDN CSP 文档](https://developer.mozilla.org/docs/Web/HTTP/CSP) +- [Tauri 配置参考](https://v2.tauri.app/reference/config/) +- [CSP 评估工具](https://csp-evaluator.withgoogle.com/) + +--- + +*最后更新: 2025-01-11* +*基于 Tauri CLI Schema v2.6.2* diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 7ec51b7..2e39653 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -25,10 +25,10 @@ } ], "security": { - "csp": "default-src 'self' ipc: http://ipc.localhost; img-src 'self' asset: http://asset.localhost data:; media-src 'self' asset: http://asset.localhost; video-src 'self' asset: http://asset.localhost; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'", + "csp": "default-src 'self'; img-src 'self' asset: data: http://asset.localhost; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; connect-src 'self' ipc: http://ipc.localhost", "assetProtocol": { "enable": true, - "scope": ["**"] + "scope": ["$HOME/**", "$DESKTOP/**", "$DOCUMENT/**"] } } },