跳到内容
Tauri

隔离模式

隔离模式是一种在前端发送的 Tauri API 消息到达 Tauri Core 之前拦截和修改它们的方法,所有这些都使用 JavaScript 完成。隔离模式注入的安全 JavaScript 代码被称为隔离应用程序。

为什么

隔离模式的目的是为开发者提供一种机制,以帮助保护他们的应用程序免受来自前端对 Tauri Core 的不必要或恶意调用。隔离模式的需求源于在前端运行不受信任内容的威胁,这在具有许多依赖项的应用程序中很常见。请参阅安全性:威胁模型,以获取应用程序可能遇到的许多威胁来源的列表。

上述描述的最大威胁模型是隔离模式设计的初衷,即开发威胁。不仅许多前端构建时工具包含许多(或数百个)通常深度嵌套的依赖项,而且复杂的应用程序也可能具有大量(也通常是深度嵌套的)依赖项,这些依赖项被捆绑到最终输出中。

何时

Tauri 强烈建议在任何可以使用隔离模式的情况下都使用它。因为隔离应用程序拦截所有来自前端的消息,所以它总是可以被使用。

当您使用外部 Tauri API 时,Tauri 也强烈建议锁定您的应用程序。作为开发者,您可以利用安全的隔离应用程序来尝试验证 IPC 输入,以确保它们在某些预期参数范围内。例如,您可能想要检查读取或写入文件的调用是否尝试访问应用程序预期位置之外的路径。另一个例子是确保 Tauri API HTTP fetch 调用仅将其 Origin 标头设置为您的应用程序期望的值。

也就是说,它拦截所有来自前端的消息,因此它甚至可以与始终开启的 API 一起使用,例如事件。由于某些事件可能会导致您自己的 Rust 代码执行操作,因此相同的验证技术可以用于它们。

如何

隔离模式的全部意义在于在您的前端和 Tauri Core 之间注入一个安全的应用程序,以拦截和修改传入的 IPC 消息。它通过使用 <iframe> 的沙箱功能来安全地与主前端应用程序一起运行 JavaScript 来实现这一点。Tauri 在加载页面时强制执行隔离模式,强制所有对 Tauri Core 的 IPC 调用首先路由到沙箱化的隔离应用程序。一旦消息准备好传递给 Tauri Core,它将使用浏览器的 SubtleCrypto 实现进行加密,然后传递回主前端应用程序。到达那里后,它将直接传递给 Tauri Core,在那里它将被解密并像正常一样读取。

为了确保没有人可以手动读取应用程序特定版本的密钥,并使用它在加密后修改消息,每次运行应用程序时都会生成新密钥。

IPC 消息的大致步骤

为了更容易理解,这里列出了一个有序列表,其中包含 IPC 消息在使用隔离模式发送到 Tauri Core 时将经历的大致步骤

  1. Tauri 的 IPC 处理程序接收消息
  2. IPC 处理程序 -> 隔离应用程序
  3. [沙箱] 隔离应用程序钩子运行并可能修改消息
  4. [沙箱] 消息使用运行时生成的密钥通过 AES-GCM 加密
  5. [已加密] 隔离应用程序 -> IPC 处理程序
  6. [已加密] IPC 处理程序 -> Tauri Core

注意:箭头 (->) 表示消息传递。

性能影响

由于消息加密确实会发生,因此与 棕地模式 相比,即使安全的隔离应用程序不执行任何操作,也会产生额外的开销成本。除了对性能敏感的应用程序(它们可能具有精心维护且小的依赖项集,以保持足够的性能)之外,大多数应用程序不应注意到加密/解密 IPC 消息的运行时成本,因为它们相对较小,并且 AES-GCM 相对较快。如果您不熟悉 AES-GCM,那么在此上下文中相关的是它是 SubtleCrypto 中包含的唯一经过身份验证的模式算法,并且您可能每天已经在 TLS 下在幕后使用它。

每次 Tauri 应用程序启动时,还会生成一个密码学上安全的密钥。如果系统已经有足够的熵来立即返回足够的随机数,这通常不会被注意到,这对于桌面环境来说非常常见。如果在无头环境中运行以使用 WebDriver 进行集成测试,那么您可能需要安装某种熵生成服务,例如 haveged,如果您的操作系统未包含一个。Linux 5.6(2020 年 3 月)现在包含使用推测执行的熵生成。

局限性

隔离模式存在一些由于平台不一致性而产生的限制。最显著的限制是由于外部文件无法在 Windows 上的沙箱 <iframes> 中正确加载。因此,我们在构建时实现了一个简单的脚本内联步骤,该步骤获取相对于隔离应用程序的脚本内容并将其内联注入。这意味着典型的捆绑或简单包含文件(如 <script src="index.js"></script>)仍然可以正常工作,但较新的机制(如 ES 模块)将无法成功加载。

建议

由于隔离应用程序的目的是防止开发威胁,我们强烈建议您尽可能保持隔离应用程序的简单性。您不仅应该努力保持依赖项最小化,还应该考虑保持所需的构建步骤最小化。这将使您无需担心针对隔离应用程序(在您的前端应用程序之上)的供应链攻击。

创建隔离应用程序

在本示例中,我们将创建一个小的 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