跳至主要内容

进程沙盒

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

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

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

从 Electron 20 开始,沙盒已为渲染器进程启用,无需任何进一步配置。如果您想为某个进程禁用沙盒,请参阅 为单个进程禁用沙盒 部分。

Electron 中的沙盒行为

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

渲染器进程

当 Electron 中的渲染器进程处于沙盒中时,它们的行为与普通的 Chrome 渲染器相同。沙盒渲染器不会初始化 Node.js 环境。

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

注意

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

预加载脚本

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

  • electron(遵循渲染器进程模块:contextBridgecrashReporteripcRenderernativeImagewebFramewebUtils
  • 事件
  • 计时器
  • URL

node: imports 也受支持

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

由于 require 函数是一个功能有限的填充函数,因此您将无法使用 CommonJS 模块 将您的预加载脚本分成多个文件。如果您需要拆分预加载代码,请使用捆绑器,例如 webpackParcel

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

配置沙盒

对于大多数应用程序来说,沙盒是最佳选择。在某些与沙盒不兼容的用例中(例如,在渲染器中使用本机节点模块时),可以为特定进程禁用沙盒。这会带来安全风险,尤其是如果在未沙盒的进程中存在任何不可信代码或内容。

为单个进程禁用沙盒

在 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 构造函数来完成。

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

全局启用沙盒

如果您想强制所有渲染器使用沙盒,也可以使用 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,但最终我们总会落后于 Chromium,因为存在一些基本问题

  1. 我们没有像 Chromium 一样专门的资源或专业知识来应用于其产品的安全性。我们尽最大努力利用现有的资源,继承 Chromium 的所有内容,并迅速响应安全问题,但如果没有 Chromium 能够投入的资源,Electron 无法像 Chromium 一样安全。
  2. Chrome 中的一些安全功能(例如安全浏览和证书透明度)需要集中式授权和专用服务器,而这两者都与 Electron 项目的目标相矛盾。因此,我们在 Electron 中禁用了这些功能,但付出了它们原本会带来的安全性的代价。
  3. 只有一个 Chromium,而有数千个基于 Electron 构建的应用程序,它们的运行方式略有不同。考虑这些差异可能会产生巨大的可能性空间,并使在不寻常的用例中确保平台安全成为挑战。
  4. 我们无法直接将安全更新推送给用户,因此我们依赖应用程序供应商来升级其应用程序底层的 Electron 版本,以便安全更新才能到达用户。

虽然我们尽最大努力将 Chromium 安全修复程序移植到旧版本的 Electron,但我们不保证所有修复程序都会被移植。保持安全的最有效方法是使用最新稳定版本的 Electron。