进程沙箱
¥Process Sandboxing
Chromium 中的一项关键安全功能是进程可以在沙箱中执行。沙箱通过限制对大多数系统资源的访问来限制恶意代码可能造成的危害 - 沙箱进程只能自由使用 CPU 周期和内存。为了执行需要额外特权的操作,沙盒进程使用专用通信通道将任务委托给更具特权的进程。
¥One key security feature in Chromium is that processes can be executed within a sandbox. The sandbox limits the harm that malicious code can cause by limiting access to most system resources — sandboxed processes can only freely use CPU cycles and memory. In order to perform operations requiring additional privilege, sandboxed processes use dedicated communication channels to delegate tasks to more privileged processes.
在 Chromium 中,沙箱应用于除主进程之外的大多数进程。这包括渲染器进程,以及音频服务、GPU 服务和网络服务等实用程序进程。
¥In Chromium, sandboxing is applied to most processes other than the main process. This includes renderer processes, as well as utility processes such as the audio service, the GPU service and the network service.
有关更多信息,请参阅 Chromium 的 沙盒设计文档。
¥See Chromium's Sandbox design document for more information.
从 Electron 20 开始,为渲染器进程启用沙箱,无需任何进一步配置。如果要禁用进程的沙箱,请参阅 禁用单个进程的沙箱 部分。
¥Starting from Electron 20, the sandbox is enabled for renderer processes without any further configuration. If you want to disable the sandbox for a process, see the Disabling the sandbox for a single process section.
Electron 中的沙箱行为
¥Sandbox behavior in Electron
Electron 中的沙盒进程的行为方式与 Chromium 的行为方式基本相同,但 Electron 有一些额外的概念需要考虑,因为它与 Node.js 交互。
¥Sandboxed processes in Electron behave mostly in the same way as Chromium's do, but Electron has a few additional concepts to consider because it interfaces with Node.js.
渲染器进程
¥Renderer processes
当 Electron 中的渲染器进程被沙箱化时,它们的行为方式与常规 Chrome 渲染器相同。沙盒渲染器不会初始化 Node.js 环境。
¥When renderer processes in Electron are sandboxed, they behave in the same way as a regular Chrome renderer would. A sandboxed renderer won't have a Node.js environment initialized.
因此,当启用沙箱时,渲染器进程只能通过进程间通信 (IPC) 将这些任务委托给主进程来执行特权任务(例如与文件系统交互、对系统进行更改或生成子进程)。
¥Therefore, when the sandbox is enabled, renderer processes can only perform privileged tasks (such as interacting with the filesystem, making changes to the system, or spawning subprocesses) by delegating these tasks to the main process via inter-process communication (IPC).
预加载脚本
¥Preload scripts
为了允许渲染器进程与主进程进行通信,附加到沙盒渲染器的预加载脚本仍将具有可用的 Node.js API 的填充子集。暴露了一个类似于 Node 的 require
模块的 require
函数,但只能导入 Electron 和 Node 内置模块的子集:
¥In order to allow renderer processes to communicate with the main process, preload
scripts attached to sandboxed renderers will still have a polyfilled subset of Node.js
APIs available. A require
function similar to Node's require
module is exposed,
but can only import a subset of Electron and Node's built-in modules:
-
electron
(以下渲染器进程模块:contextBridge
、crashReporter
、ipcRenderer
、nativeImage
、webFrame
、webUtils
)¥
electron
(following renderer process modules:contextBridge
,crashReporter
,ipcRenderer
,nativeImage
,webFrame
,webUtils
)
还支持 节点:imports:
¥node: imports are supported as well:
此外,预加载脚本还将某些 Node.js 基础类型填充为全局变量:
¥In addition, the preload script also polyfills certain Node.js primitives as globals:
由于 require
函数是功能有限的填充程序,因此你将无法使用 CommonJS 模块 将预加载脚本分离到多个文件中。如果你需要拆分预加载代码,请使用 webpack 或 Parcel 等打包器。
¥Because the require
function is a polyfill with limited functionality, you will not be
able to use CommonJS modules to separate your preload script into multiple
files. If you need to split your preload code, use a bundler such as webpack
or Parcel.
请注意,由于提供给 preload
脚本的环境比沙盒渲染器的环境具有更高的特权,因此仍然有可能将特权 API 泄漏给渲染器进程中运行的不受信任的代码,除非启用 contextIsolation
。
¥Note that because the environment presented to the preload
script is substantially
more privileged than that of a sandboxed renderer, it is still possible to leak
privileged APIs to untrusted code running in the renderer process unless
contextIsolation
is enabled.
配置沙箱
¥Configuring the sandbox
对于大多数应用来说,沙箱是最佳选择。在某些与沙箱不兼容的用例中(例如,在渲染器中使用原生 Node 模块时),可以禁用特定进程的沙箱。这会带来安全风险,特别是如果非沙盒进程中存在任何不受信任的代码或内容。
¥For most apps, sandboxing is the best choice. In certain use cases that are incompatible with the sandbox (for instance, when using native node modules in the renderer), it is possible to disable the sandbox for specific processes. This comes with security risks, especially if any untrusted code or content is present in the unsandboxed process.
禁用单个进程的沙箱
¥Disabling the sandbox for a single process
在 Electron 中,可以使用 BrowserWindow
构造函数中的 sandbox: false
首选项在每个进程的基础上禁用渲染器沙箱。
¥In Electron, renderer sandboxing can be disabled on a per-process basis with
the sandbox: false
preference in the BrowserWindow
constructor.
app.whenReady().then(() => {
const win = new BrowserWindow({
webPreferences: {
sandbox: false
}
})
win.loadURL('https://google.com')
})
只要在渲染器中启用 Node.js 集成,沙箱也会被禁用。这可以通过带有 nodeIntegration: true
标志的 BrowserWindow 构造函数来完成。
¥Sandboxing is also disabled whenever Node.js integration is enabled in the renderer.
This can be done through the BrowserWindow constructor with the nodeIntegration: true
flag.
app.whenReady().then(() => {
const win = new BrowserWindow({
webPreferences: {
nodeIntegration: true
}
})
win.loadURL('https://google.com')
})
全局启用沙箱
¥Enabling the sandbox globally
如果你想对所有渲染器强制沙箱,你也可以使用 app.enableSandbox
API。请注意,必须在应用的 ready
事件之前调用此 API。
¥If you want to force sandboxing for all renderers, you can also use the
app.enableSandbox
API. Note that this API has to be called before the
app's ready
event.
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 的沙箱(仅测试)
¥Disabling Chromium's sandbox (testing only)
你还可以使用 --no-sandbox
CLI 标志完全禁用 Chromium 的沙箱,这将禁用所有进程(包括实用程序进程)的沙箱。我们强烈建议你仅将此标志用于测试目的,切勿在生产中使用。
¥You can also disable Chromium's sandbox entirely with the --no-sandbox
CLI flag, which will disable the sandbox for all processes (including utility processes).
We highly recommend that you only use this flag for testing purposes, and never
in production.
请注意,sandbox: true
选项仍会禁用渲染器的 Node.js 环境。
¥Note that the sandbox: true
option will still disable the renderer's Node.js
environment.
关于渲染不受信任内容的注意事项
¥A note on rendering untrusted content
尽管一些应用正在取得成功(例如 烧杯浏览器),但在 Electron 中渲染不受信任的内容仍然是一个未知字段。我们的目标是在沙盒内容的安全性方面尽可能接近 Chrome,但最终由于一些基本问题,我们将永远落后:
¥Rendering untrusted content in Electron is still somewhat uncharted territory, though some apps are finding success (e.g. Beaker Browser). Our goal is to get as close to Chrome as we can in terms of the security of sandboxed content, but ultimately we will always be behind due to a few fundamental issues:
-
我们没有 Chromium 所需的专用资源或专业知识来确保其产品的安全性。我们尽最大努力利用我们所拥有的资源,从 Chromium 继承一切,并快速响应安全问题,但如果没有 Chromium 能够提供的资源,Electron 就不可能像 Chromium 那样安全。
¥We do not have the dedicated resources or expertise that Chromium has to apply to the security of its product. We do our best to make use of what we have, to inherit everything we can from Chromium, and to respond quickly to security issues, but Electron cannot be as secure as Chromium without the resources that Chromium is able to dedicate.
-
Chrome 中的一些安全功能(例如安全浏览和证书透明度)需要集中权限和专用服务器,这两者都与 Electron 项目的目标背道而驰。因此,我们在 Electron 中禁用这些功能,但代价是它们本来会带来的相关安全性。
¥Some security features in Chrome (such as Safe Browsing and Certificate Transparency) require a centralized authority and dedicated servers, both of which run counter to the goals of the Electron project. As such, we disable those features in Electron, at the cost of the associated security they would otherwise bring.
-
只有一种 Chromium,而有成千上万个基于 Electron 构建的应用,所有这些应用的行为都略有不同。考虑到这些差异可能会产生巨大的可能性空间,并使在异常用例中确保平台的安全性变得具有挑战性。
¥There is only one Chromium, whereas there are many thousands of apps built on Electron, all of which behave slightly differently. Accounting for those differences can yield a huge possibility space, and make it challenging to ensure the security of the platform in unusual use cases.
-
我们无法直接向用户推送安全更新,因此我们依靠应用提供者升级其应用底层的 Electron 版本,以便将安全更新发送给用户。
¥We can't push security updates to users directly, so we rely on app vendors to upgrade the version of Electron underlying their app in order for security updates to reach users.
虽然我们尽最大努力将 Chromium 安全修复程序向后移植到旧版本的 Electron,但我们不保证每个修复程序都会向后移植。保持安全的最佳机会是使用最新稳定版本的 Electron。
¥While we make our best effort to backport Chromium security fixes to older versions of Electron, we do not make a guarantee that every fix will be backported. Your best chance at staying secure is to be on the latest stable version of Electron.