Rust in Everything
基于 tauri 2.12.5

安全

tauri 把 UI 整个交给前端,前端里的任何 JS 都能拿到 __TAURI_INTERNALS__.invoke。这一部分讲 tauri 用什么来限制这些 JS 能做的事。主体是 ACL:源码在 tauri-utils/src/acl/(数据结构和解析,约 2.5k 行)和 tauri/src/ipc/authority.rs(运行时,1.6k 行);其余是前端侧的几层:CSP(manager/mod.rs)、freezePrototype、隔离模式(protocol/isolation.rs、tauri-utils/src/pattern/、几个 JS 文件)。

  1. 权限、能力、作用域:权限列出允许和拒绝的命令、可带作用域;权限集把权限编组,default 是名字固定的权限集;能力把权限交给匹配 windows / webviews 模式的 webview,在本地和 / 或 remote.urls 来源下生效。标识符的规则,以及作用域怎么以 CommandScope<T> / GlobalScope<T> 交给命令。
  2. 编译期解析:Resolved::resolve 把能力展开成「命令 → 允许它的窗口、webview、来源和作用域编号」的表,没有命令的权限进全局作用域,允许和拒绝分开存、不在这里裁决;dump 一个小应用的结果;add_capability 怎么在运行时追加,以及写错权限名时它 panic 而不是返回 Err。
  3. 运行时检查:on_message 里的 resolve_access:允许要来源和标签都匹配,拒绝只看来源;debug 和 release 的拒绝原文;remote.urls 匹配的是 Origin 头;没有应用权限清单时应用命令的豁免到底意味着什么;全局作用域按包名找插件。
  4. CSP、原型冻结与隔离模式:编译期哈希和运行时 nonce 怎么补进 CSP 头,CSP 挡住什么、挡不住 tauri 自己的哪些通道;freezePrototype 的实测;隔离模式的 iframe、钩子和 AES-GCM,以及它保证什么、不管什么。
flowchart TB
  files["权限文件 能力文件"] --> build["tauri-build 收集校验"]
  build --> ctx["generate_context! 解析"]
  ctx --> resolved["Resolved 编进二进制"]
  resolved --> auth["RuntimeAuthority"]
  dyn["add_capability"] --> auth
  js["页面 JS invoke"] --> iso["隔离 iframe 可选"]
  iso --> ipc["ipc 协议"]
  js --> ipc
  ipc --> onmsg["on_message"]
  auth --> onmsg
  onmsg --> cmd["命令 拿到作用域"]
  csp["CSP 头 原型冻结"] --> js

权限文件怎么从插件 crate 传到应用、在构建时怎么校验,在 tauri-build;解析结果怎么写进 Context,在 generate_context!;ACL 检查之前的 invoke key 和之后的分发,在 on_message 与分发。插件命令的权限命名在插件。

本部分的实验有两类:不需要窗口的(ACL 解析、拒绝信息、作用域)跑在 tauri::test 的 MockRuntime 上;和来源、webview 有关的(窗口标签、远程页面、CSP、隔离模式)是真实的 tauri 应用,窗口全部隐藏,远程页面由本机 127.0.0.1 上的 HTTP 服务提供。平台 M2 Max、macOS 27、rustc 1.99.0,Windows 和 Linux 只读了源码。拒绝信息在 debug 和 release 下不同,两种都给出。

💬 关联讨论

发起讨论
加载中...