跳至主要内容

进程沙箱

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

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

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

从 Electron 20 开始,渲染器进程默认启用沙箱,无需额外配置。如果你想禁用某个进程的沙箱,请参阅 禁用单个进程的沙箱 部分。

Electron 中的沙箱行为

Electron 中的沙箱化进程的行为方式 基本上 与 Chromium 中的相同,但由于 Electron 与 Node.js 交互,因此还有一些额外的概念需要考虑。

渲染器进程

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

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

注意

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

预加载脚本

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

  • electron (以下渲染器进程模块:contextBridgecrashReporteripcRenderernativeImagewebFramewebUtils)
  • events
  • timers
  • url

node: imports 也支持

此外,预加载脚本还将某些 Node.js 原生类型 polyfill 为全局变量

由于 `require` 函数是一个功能受限的 polyfill,你将无法使用 CommonJS 模块将预加载脚本分离到多个文件中。如果你需要拆分预加载代码,请使用像 webpackParcel 这样的打包器。

请注意,由于提供给 `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 构造函数来完成。

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,但由于一些根本性问题,我们最终总是会落后

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

虽然我们尽最大努力将 Chromium 安全修复程序向后移植到旧版本的 Electron,但我们不保证每个修复程序都会被向后移植。保持安全的最佳途径是使用最新稳定版本的 Electron。