进程沙箱
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.js 原语 polyfill 为全局变量
因为 require
函数是一个功能有限的 polyfill,您将无法使用 CommonJS 模块 将您的预加载脚本分成多个文件。如果您需要拆分预加载代码,请使用捆绑器,例如 webpack 或 Parcel。
请注意,由于呈现给 preload
脚本的环境比沙箱渲染器的环境具有更高的权限,因此仍然可以将特权 API 泄漏到在渲染器进程中运行的不受信任的代码,除非启用contextIsolation
。
配置沙箱
对于大多数应用程序,沙箱是最佳选择。 在某些与沙箱不兼容的用例中(例如,在渲染器中使用本机节点模块时),可以为特定进程禁用沙箱。 这会带来安全风险,尤其是在未沙箱化的进程中存在任何不受信任的代码或内容时。
为单个进程禁用沙箱
在 Electron 中,可以使用 BrowserWindow
构造函数中的 sandbox: false
首选项为每个进程禁用渲染器沙箱。
app.whenReady().then(() => {
const win = new BrowserWindow({
webPreferences: {
sandbox: false
}
})
win.loadURL('https://google.com')
})
只要在渲染器中启用 Node.js 集成,也会禁用沙箱。 可以通过使用 nodeIntegration: true
标志的 BrowserWindow 构造函数来完成此操作。
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,但由于一些基本问题,我们最终总是会落后于 Chrome
- 我们没有 Chromium 所拥有的专门资源或专业知识来应用于其产品的安全性。 我们尽最大努力利用我们所拥有的,从 Chromium 继承一切,并快速响应安全问题,但如果没有 Chromium 能够投入的资源,Electron 不可能像 Chromium 那样安全。
- Chrome 中的某些安全功能(例如安全浏览和证书透明度)需要一个集中机构和专用服务器,这两者都与 Electron 项目的目标背道而驰。 因此,我们在 Electron 中禁用了这些功能,代价是它们原本会带来的相关安全性。
- 只有一个 Chromium,而有成千上万个基于 Electron 构建的应用程序,所有应用程序的行为都略有不同。 考虑到这些差异可能会产生巨大的可能性空间,并且很难确保该平台在不寻常的用例中的安全性。
- 我们无法直接向用户推送安全更新,因此我们依赖于应用程序供应商来升级其应用程序底层的 Electron 版本,以便安全更新能够到达用户。
虽然我们尽最大努力将 Chromium 安全修复程序向后移植到旧版本的 Electron,但我们不保证每个修复程序都会向后移植。 保持安全的最佳机会是使用最新的稳定版 Electron。