跳转到主要内容

进程沙箱

Chromium 的一项关键安全特性是进程可以在沙箱内执行。沙箱通过限制对大多数系统资源的访问来限制恶意代码造成的损害——沙箱进程只能自由使用 CPU 周期和内存。为了执行需要额外权限的操作,沙箱进程使用专用的通信通道将任务委派给权限更高的进程。

在 Chromium 中,沙箱应用于除主进程以外的大多数进程。这包括渲染进程以及音频服务、GPU 服务和网络服务等实用程序进程。

有关更多信息,请参阅 Chromium 的 沙箱设计文档

从 Electron 20 开始,沙箱已为渲染进程启用,无需进一步配置。

沙箱与 Node.js 集成相关联。启用 Node.js 集成 对于渲染进程,通过设置 nodeIntegration: true 会禁用该进程的沙箱

如果您想为某个进程禁用沙箱,请参阅 为单个进程禁用沙箱 部分。

Electron 中的沙箱行为

Electron 中的沙箱进程的行为大致与 Chromium 中的行为相同,但 Electron 有一些额外的概念需要考虑,因为它与 Node.js 交互。

渲染进程

当 Electron 中的渲染进程被沙箱化时,它们的行为方式与常规 Chrome 渲染器相同。沙箱化的渲染器不会初始化 Node.js 环境。

因此,当沙箱启用时,渲染进程只能通过进程间通信 (IPC) 将任务(例如与文件系统交互、更改系统或生成子进程)委派给主进程来执行特权任务。

注意

有关进程间通信的更多信息,请查看我们的 IPC 指南

预加载脚本

为了允许渲染进程与主进程通信,附加到沙箱化渲染器的预加载脚本仍然可以使用多填写的 Node.js API 子集。暴露了一个类似于 Node 的 require 模块的 require 函数,但只能导入 Electron 和 Node 的内置模块的子集

  • electron (以下渲染进程模块:contextBridge, crashReporter, ipcRenderer, nativeImage, webFrame, webUtils)
  • events
  • timers
  • url

node: imports 也受支持

此外,预加载脚本还会将某些 Node.js 原语作为全局变量多填写

由于 require 函数是一个具有有限功能的填充,因此您将无法使用 CommonJS 模块 将预加载脚本拆分为多个文件。如果您需要拆分预加载代码,请使用 webpack 或 Parcel 等打包器。

请注意,由于呈现给 preload 脚本的环境比沙箱化渲染器的环境权限更高,因此,除非启用 contextIsolation,否则仍然有可能将特权 API 泄漏到在渲染器进程中运行的不可信代码中。

配置沙箱

对于大多数应用程序,沙箱是最佳选择。在某些与沙箱不兼容的使用案例中(例如,在渲染器中使用本机 node 模块),可以为特定进程禁用沙箱。这样做存在安全风险,尤其是在未沙箱化进程中存在任何不可信代码或内容的情况下。

为单个进程禁用沙箱

在 Electron 中,可以使用 BrowserWindow 构造函数中的 sandbox: false 首选项按进程禁用渲染器沙箱。

main.js
app.whenReady().then(() => {
const win = new BrowserWindow({
webPreferences: {
sandbox: false
}
})
win.loadURL('https://google.com')
})

每当在渲染器中启用 Node.js 集成时,也会禁用沙箱。这可以通过 nodeIntegration: true 标志在 BrowserWindow 构造函数中完成,或者通过为 webview 提供相应的 HTML 布尔属性来完成。

main.js
app.whenReady().then(() => {
const win = new BrowserWindow({
webPreferences: {
nodeIntegration: true
}
})
win.loadURL('https://google.com')
})
index.html (渲染进程)
<webview nodeIntegration src="page.html"></webview>

全局启用沙箱

如果您想强制为所有渲染器启用沙箱,您还可以使用 app.enableSandbox API。请注意,此 API 必须在应用程序的 ready 事件之前调用。

main.js
app.enableSandbox()
app.whenReady().then(() => {
// any sandbox:false calls are overridden since `app.enableSandbox()` was called.
const win = new BrowserWindow()
win.loadURL('https://google.com')
})

禁用 Chromium 的沙箱(仅用于测试)

您还可以使用 --no-sandbox CLI 标志完全禁用 Chromium 的沙箱,这将禁用所有进程(包括实用程序进程)的沙箱。我们强烈建议您仅将此标志用于测试目的,绝不在生产环境中使用。

请注意,sandbox: true 选项仍然会禁用渲染器的 Node.js 环境。

关于渲染不受信任的内容的说明

在 Electron 中渲染不受信任的内容仍然是一个未知的领域,尽管有些应用程序正在取得成功(例如,Beaker Browser)。我们的目标是在沙箱化内容的安全性方面尽可能接近 Chrome,但最终由于一些基本问题,我们将始终落后。

  1. 我们没有像 Chromium 那样专门的资源和专业知识来应用于其产品的安全性。我们尽最大努力利用我们所拥有的资源,继承我们能从 Chromium 继承的一切,并快速响应安全问题,但 Electron 无法像 Chromium 那样安全,而 Chromium 能够投入的资源。
  2. Chrome 中的某些安全功能(例如安全浏览和证书透明度)需要集中式权威机构和专用服务器,这两者都与 Electron 项目的目标背道而驰。因此,我们在 Electron 中禁用这些功能,代价是它们原本会带来的相关安全性。
  3. 只有一个 Chromium,而有成千上万的应用程序构建在 Electron 之上,所有这些应用程序的行为都略有不同。考虑这些差异可能会产生巨大的可能性空间,并使确保平台在异常使用情况下的安全性变得具有挑战性。
  4. 我们无法直接向用户推送安全更新,因此我们依赖应用程序供应商升级应用程序底层的 Electron 版本,以便安全更新能够到达用户。

虽然我们尽最大努力将 Chromium 安全修复程序回溯到旧版本的 Electron,但我们不保证会回溯每个修复程序。您保持安全的最佳机会是使用最新稳定的 Electron 版本。