上锁先立总纲。本节讲 Tauri 安全模型的第一性原理——默认拒绝与最小权限,说明三道默认防线各防住什么,并给"安全配置"一个新定位:它不是发布前的检查项,而是功能设计的输入。读懂总纲,后面三节的具体操作才有判断依据。
回想 2.1 的分层:页面的 JS 上下文里本来就没有文件、网络、进程能力——这些全部住在 Rust 芯。前端想用,只能经命令或插件 API 跨桥,而桥上驻着权限闸门(2.2 的第三站)。这个架构决定带来一个关键性质:WebView 里跑的任何脚本,能做的事完全等于闸门放行的事。恶意脚本不是"破解你的文件系统",而是"冒充你的前端去叫命令"——安全问题的形状从"防线被攻破"变成了"门禁被冒用",而门禁冒用是权限管理问题,权限管理有成熟解法。
防线一:能力默认关闭。 未经 Capabilities 授权的插件命令,调用直接被拒。对比"默认全开、靠开发者自觉关闭"的模型,默认拒绝的错误方向是"少给了功能"——症状明显(功能不工作),开发期就暴露;默认全开的错误方向是"多给了权限"——症状是静默的,可能上线很久都没人发现。错误方向朝哪边偏,决定了系统是越用越严还是越用越松。
防线二:CSP 默认收紧。 生产构建自动注入内容安全策略,默认只许加载自身资源(3.3 的 security 段)。外链脚本、内联事件处理器这些经典注入通道在默认策略下失效。
防线三:上下文隔离。 Tauri 的 IPC 层不把 Rust 对象或句柄暴露到页面全局;前端拿到的只有异步调用接口。即便脚本在页面里拿到了 invoke 的引用,它能调到的也只限于授权集合内的命令名,拿不到任何底层对象。
三道防线的共同点是不需要你记得开启。安全机制分两种:一种是"默认在、可以关",一种是"默认没、记得开"。Tauri 的核心防线属于前者——这是它与"给开发者发一份安全清单自觉执行"方案的本质差别。
防线的"默认"长什么样,值得在动手前看一眼实物。新建项目的权限目录里只有一份最小清单,指向一个空权限集:
# capabilities/default.json —— 脚手架给出的起点 identifier: default windows: [main] permissions: []
permissions 为空意味着此刻前端连一个系统调用都做不了——invoke 任何插件命令都会吃到权限拒绝。这不是故障,是总纲的具象化:起点是零,每一个能力都必须经过显式申请才进入清单。对照"默认全开"方案那份动辄几十行的预授权列表,两种起点的差别就是两种安全姿态的差别。三道防线里,第一道归 6.2 的 Capabilities 机制管,第二道归 6.3 的 CSP 配置管,第三道由框架内建、无需配置——本节的义务是记住它们的边界,后续两节负责把前两道拧到合适的松紧。
原则人人会背,难在操作化。给三条可执行的判据:
判据一:按功能授权,不按插件授权。 需要"保存对话框"不等于需要 dialog 插件全部命令——只授 save,不授 message、ask、confirm。粒度到命令级,不是到插件级。
判据二:按窗口授边界。 主窗需要读写笔记目录,关于窗口什么都不需要——权限文件按窗口分开写,别用一张大而全的清单喂所有窗口。第 4 章的多窗口标签在这里变成安全边界。
判据三:路径授权到目录级。 授 fs 读权限时给具体目录作用域(笔记目录),不给整个用户目录,更不给通配全盘。作用域的具体写法在 6.2 展开。
判据好不好用,要放到攻击面前量一量。假设笔记应用渲染层出了一条漏报的注入:用户导入了一份来路不明的笔记文件,里面的批注字段藏了一段脚本,渲染时被当成 HTML 执行了。现在攻击者的代码已经跑在页面里,接下来会发生什么?
它第一件事通常是摸家底:试着调 window.__TAURI__。在 Tauri 2 里这个全局对象默认根本不注入,脚本能拿到的只有桥接层挂上的最小 invoke 入口。它转而直接叫命令名,推演结果取决于权限清单长什么样:
| 攻击动作 | 默认拒绝清单下 | 一张"图省事"的全开清单下 |
|---|---|---|
| 调用未授权的插件命令 | 桥上直接拒绝,返回权限错误 | 命令执行,文件被读走 |
| 读笔记目录之外的路径 | 作用域拦截,路径越界报错 | 全盘可读,凭据文件遭殃 |
| 加载外部脚本加深攻击 | CSP 拦截外链,脚本无法二段加载 | 远程代码自由进入 |
| 探测底层 Rust 对象 | 上下文隔离,拿到的只有异步接口 | 视集成方式而定,可能暴露句柄 |
这张表左列是同一只红队,右列的差异完全由权限决策决定——这正是"门禁被冒用"这个定性想说的:**注入能否升级成事故,不取决于注入本身,取决于闸门后面有什么。**全开清单的持有者不是没有安全机制,而是把机制配置成了不设防;默认拒绝的持有者即便漏了净化,攻击者拿到的也只是一个空房间。推演还能再进一步:即便清单里确实有 fs 读权限(笔记应用总得读文件),6.2 的目录作用域也会把损失压在笔记目录内——攻击者读完笔记,仅此而已。安全设计做不到消灭漏洞,能做到的是给每一个漏洞标定天花板。
总纲的最后一块拼图,是把安全决策前移到功能设计期:

总纲立好。下一节动手写权限文件:给随身笔记发放第一张门禁卡,再收回两张发多了的。