进程沙盒
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` (以下渲染器进程模块:`contextBridge`, `crashReporter`, `ipcRenderer`, `nativeImage`, `webFrame`, `webUtils`)
events
timers
url
node: 导入也受支持
此外,预加载脚本还将某些 Node.js 原生类型作为全局变量进行 polyfill
由于 `require` 函数是一个功能受限的 polyfill,您将无法使用CommonJS 模块将预加载脚本拆分为多个文件。如果需要拆分预加载代码,请使用 webpack 或 Parcel 等打包工具。
请注意,由于提供给 `preload` 脚本的环境比沙盒渲染器的环境具有更高的权限,因此除非启用`contextIsolation`,否则仍有可能将特权 API 泄露给在渲染器进程中运行的不可信代码。
配置沙盒
对于大多数应用程序,沙盒是最佳选择。在某些与沙盒不兼容的用例中(例如,在渲染器中使用原生 Node 模块时),可以为特定进程禁用沙盒。这会带来安全风险,特别是如果未沙盒化的进程中存在任何不可信的代码或内容。
禁用单个进程的沙盒
在 Electron 中,渲染器沙盒可以通过 `BrowserWindow` 构造函数中的 `sandbox: false` 偏好设置,按每个进程禁用。
app.whenReady().then(() => {
const win = new BrowserWindow({
webPreferences: {
sandbox: false
}
})
win.loadURL('https://google.com')
})
当渲染器中启用 Node.js 集成时,沙盒也会被禁用。这可以通过 `BrowserWindow` 构造函数中的 `nodeIntegration: true` 标志完成。
app.whenReady().then(() => {
const win = new BrowserWindow({
webPreferences: {
nodeIntegration: true
}
})
win.loadURL('https://google.com')
})
全局启用沙盒
如果您想强制所有渲染器使用沙盒,也可以使用 `app.enableSandbox` API。请注意,此 API 必须在应用程序的 `ready` 事件之前调用。
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 浏览器)。我们的目标是在沙盒内容的安全性方面尽可能地接近 Chrome,但最终由于一些根本性问题,我们总是会落后
- 我们没有 Chromium 专门用于产品安全方面的资源或专业知识。我们尽最大努力利用我们所拥有的,从 Chromium 继承一切我们可以继承的,并快速响应安全问题,但如果没有 Chromium 能够投入的资源,Electron 不可能像 Chromium 那样安全。
- Chrome 中的某些安全功能(例如安全浏览和证书透明度)需要一个集中式机构和专用服务器,这两者都与 Electron 项目的目标相悖。因此,我们在 Electron 中禁用了这些功能,代价是它们原本会带来的相关安全性。
- 只有一个 Chromium,而基于 Electron 构建的应用程序有成千上万个,它们都有细微的行为差异。考虑到这些差异会产生巨大的可能性空间,使得在不寻常的用例中确保平台安全变得具有挑战性。
- 我们无法直接向用户推送安全更新,因此我们依赖应用程序供应商升级其应用程序所使用的 Electron 版本,以便安全更新能够送达用户。
尽管我们尽最大努力将 Chromium 安全修复程序向后移植到较旧的 Electron 版本,但我们不保证每个修复程序都会被向后移植。保持安全的最佳方法是使用最新稳定版本的 Electron。