隔离模式
隔离模式是一种方法,可以拦截和修改在前端发送给 Tauri Core 之前的 Tauri API 消息,这一切都是通过 JavaScript 实现的。由隔离模式注入的安全 JavaScript 代码被称为隔离应用程序。
原因
隔离模式的目的在于为开发者提供一种机制来帮助他们保护应用程序免受不受欢迎或恶意的前端对 Tauri Core 的调用。隔离模式的需求源于来自前端运行的不受信任内容带来的威胁,这是具有许多依赖项的应用程序的常见情况。有关应用程序可能遇到的许多威胁来源的列表,请参阅安全:威胁模型。
上述最大威胁模型是开发威胁,隔离模式正是针对这种威胁模型设计的。不仅许多前端构建时工具包含许多数十个(或数百个)通常深度嵌套的依赖项,而且复杂的应用程序也可能包含大量的(通常也是深度嵌套的)依赖项,这些依赖项被捆绑到最终输出中。
时间
Tauri 强烈推荐在可能的情况下使用隔离模式。因为隔离应用程序拦截来自前端的所有消息,所以它始终可以使用。
此外,每当您使用外部 Tauri API 时,Tauri 也强烈建议您锁定您的应用程序。作为开发者,您可以使用安全的隔离应用程序来尝试验证 IPC 输入,以确保它们在预期的参数范围内。例如,您可能希望检查调用读取或写入文件是否试图访问应用程序预期的位置之外的路径。另一个例子是确保 Tauri API HTTP 获取调用只设置 Origin 标头为您应用程序期望的值。
但是,它拦截来自前端的所有消息,因此它甚至可以与始终开启的 API,如 事件 一起工作。由于某些事件可能会导致您的自己的 rust 代码执行操作,因此可以使用类似的验证技术来处理这些事件。
方式
隔离模式涉及在您的前端和 Tauri Core 之间注入一个安全应用程序来拦截和修改传入的 IPC 消息。它是通过使用 <iframe>
的沙箱功能在主前端应用程序旁边安全地运行 JavaScript 来实现的。Tauri 在加载页面时强制执行隔离模式,迫使所有 IPC 调用首先通过沙箱化的隔离应用程序路由。一旦消息准备就绪并传递给 Tauri Core,它就会使用浏览器的 SubtleCrypto 实现加密,然后传递回主前端应用程序。在那里,它直接传递给 Tauri Core,然后像正常一样解密和读取。
为了确保某人无法手动读取应用程序特定版本的密钥并使用这些密钥在加密后修改消息,每次运行应用程序时都会生成新的密钥。
IPC 消息的大致步骤
为了便于理解,以下是使用隔离模式将IPC消息发送到Tauri核心的步骤概览:
- Tauri的IPC处理器接收一条消息
- IPC处理器 -> 隔离应用程序
[sandbox]
隔离应用程序钩子运行并可能修改消息[sandbox]
消息使用AES-GCM和运行时生成的密钥进行加密[encrypted]
隔离应用程序 -> IPC处理器[encrypted]
IPC处理器 -> Tauri核心
注意:箭头(->)表示消息传递。
性能影响
由于消息加密确实会发生,所以相对于Brownfield模式,有额外的开销成本,即使安全的隔离应用程序什么都不做也是如此。对于性能敏感的应用程序(这些应用程序可能有一个精心维护且依赖项很少的小集合,以保持性能),大多数应用程序应该不会注意到加密/解密IPC消息的运行时成本,因为它们相对较小,AES-GCM相对较快。如果您不熟悉AES-GCM,在本上下文中,所有相关的是它只包含在SubtleCrypto中的认证模式算法,并且您可能已经在底层使用TLS每天使用它。
还有一个加密密钥,在每次启动Tauri应用程序时都会生成一次。如果系统已有足够的熵立即返回足够的随机数,通常这是桌面环境极其常见的情况,那么这通常不会引人注意。如果在无头环境中运行以执行一些与WebDriver的集成测试,那么如果您的操作系统没有包含此类服务,您可能需要安装一种生成熵的服务,例如haveged
。Linux 5.6(2020年3月)现在使用推测执行生成熵。
限制
由于出现了一些平台不一致,隔离模式存在一些限制。最显著的限制是由于Windows上沙盒<iframes>
中的外部文件加载不正确。因此,我们在构建时实现了一个简单的内联脚本步骤,它将隔离应用程序的脚本内容内联注入。这意味着典型的捆绑或简单的文件包括<script src="index.js"></script>
仍然可以正常工作,但较新的机制如ES Modules将无法成功加载。
建议
由于隔离应用程序的目的是为了防止开发威胁,我们强烈建议尽可能保持隔离应用程序的简单性。您不仅应该力争保持依赖项最小化,还应该考虑保持所需的构建步骤最小化。这将使您无需担心对您的隔离应用程序的供应链攻击,您的隔离应用程序位于您的前端应用程序之上。
创建隔离应用程序
在本示例中,我们将创建一个小型hello-world样式的隔离应用程序,并将其连接到一个假想的现有的Tauri应用程序。它不会对通过它的消息进行验证,只会将其内容打印到WebView控制台。
为了本例的目的,让我们假设我们与tauri.conf.json
位于同一目录下。现有的Tauri应用程序的distDir
设置为../dist
。
../dist-isolation/index.html
:
<!doctype html><html lang="en"> <head> <meta charset="UTF-8" /> <title>Isolation Secure Script</title> </head> <body> <script src="index.js"></script> </body></html>
../dist-isolation/index.js
:
window.__TAURI_ISOLATION_HOOK__ = (payload) => { // let's not verify or modify anything, just print the content from the hook console.log('hook', payload); return payload;};
现在,我们只需要设置我们的 tauri.conf.json
配置 以使用隔离模式,并已从 现有系统模式 初始化到隔离模式。
配置
假设我们的主前端 distDir
设置为 ../dist
。我们还将隔离应用程序输出到 ../dist-isolation
。
{ "build": { "distDir": "../dist" }, "app": { "security": { "pattern": { "use": "isolation", "options": { "dir": "../dist-isolation" } } } }}
© 2025 Tauri 投资者。CC-BY / MIT