Skip to main content

Process Sandboxing过程沙箱

One key security feature in Chromium is that processes can be executed within a sandbox. Chromium的一个关键安全特性是进程可以在沙箱中执行。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. 沙盒通过限制对大多数系统资源的访问来限制恶意代码可能造成的危害-沙盒进程只能自由使用CPU周期和内存。In order to perform operations requiring additional privilege, sandboxed processes use dedicated communication channels to delegate tasks to more privileged processes.为了执行需要额外特权的操作,沙盒进程使用专用通信通道将任务委托给特权更高的进程。

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.这包括渲染器进程以及实用程序进程,如音频服务、GPU服务和网络服务。

See Chromium's Sandbox design document for more information.有关更多信息,请参阅Chromium的沙盒设计文档

Electron's sandboxing policiesElectron的沙箱策略

Electron comes with a mixed sandbox environment, meaning sandboxed processes can run alongside privileged ones. Electron提供了混合沙盒环境,这意味着沙盒进程可以与特权进程并行运行。By default, renderer processes are not sandboxed, but utility processes are. 默认情况下,渲染器进程不是沙盒,而是实用程序进程。Note that as in Chromium, the main (browser) process is privileged and cannot be sandboxed.请注意,在Chromium中,主(浏览器)进程是特权的,不能进行沙盒。

Historically, this mixed sandbox approach was established because having Node.js available in the renderer is an extremely powerful tool for app developers. 从历史上看,这种混合沙盒方法的建立是因为在渲染器中提供Node.js对于应用程序开发人员来说是一个非常强大的工具。Unfortunately, this feature is also an equally massive security vulnerability.不幸的是,此功能也是一个同样巨大的安全漏洞。

Theoretically, unsandboxed renderers are not a problem for desktop applications that only display trusted code, but they make Electron less secure than Chromium for displaying untrusted web content. 理论上,对于只显示可信代码的桌面应用程序来说,未打包的渲染器不是问题,但它们使Electron在显示不可信的web内容时比Chromium更不安全。However, even purportedly trusted code may be dangerous — there are countless attack vectors that malicious actors can use, from cross-site scripting to content injection to man-in-the-middle attacks on remotely loaded websites, just to name a few. 然而,即使是所谓的可信代码也可能是危险的-恶意参与者可以使用无数的攻击向量,从跨站点脚本到内容注入,再到远程加载网站上的中间人攻击,仅举几个例子。For this reason, we recommend enabling renderer sandboxing for the vast majority of cases under an abundance of caution.出于这个原因,我们建议在大多数情况下启用渲染器沙箱,但要非常谨慎。

Note that there is an active discussion in the issue tracker to enable renderer sandboxing by default. 请注意,问题跟踪程序中有一个活跃的讨论,默认情况下启用渲染器沙箱。See #28466) for details.详见#28466)。

Sandbox behaviour in ElectronElectron中的沙盒行为

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.Electron中的沙盒过程与Chromium的行为方式基本相同,但Electron还有一些额外的概念需要考虑,因为它与Node.js接口。

Renderer processes渲染器进程

When renderer processes in Electron are sandboxed, they behave in the same way as a regular Chrome renderer would. 当Electron中的渲染器进程是沙盒时,它们的行为方式与常规Chrome渲染器相同。A sandboxed renderer won't have a Node.js environment initialized.沙盒渲染器不会初始化Node.js环境。

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

Preload scripts预加载脚本

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. 为了允许渲染器进程与主进程通信,附加到沙盒渲染器的预加载脚本仍将有一个多填充的Node.js API子集可用。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:一个类似于节点的require模块的require函数被公开,但只能导入Electron和节点内置模块的子集:

  • electron (only renderer process modules)(仅适用于渲染器进程模块)
  • events
  • timers
  • url

In addition, the preload script also polyfills certain Node.js primitives as globals:此外,预加载脚本还将某些Node.js原语聚合为全局:

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. 由于require函数是一个功能有限的polyfill函数,因此您将无法使用CommonJS模块将预加载脚本分离为多个文件。If you need to split your preload code, use a bundler such as webpack or Parcel.如果需要拆分预加载代码,请使用捆绑器,如webpackParcel

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.请注意,由于呈现给preload脚本的环境比沙盒渲染器的环境具有更高的特权,因此,除非启用了contextIsolation,否则仍有可能将特权API泄漏到渲染器进程中运行的不受信任代码。

Configuring the sandbox配置沙盒

Enabling the sandbox for a single process为单个进程启用沙盒

In Electron, renderer sandboxing can be enabled on a per-process basis with the sandbox: true preference in the BrowserWindow constructor.在Electron中,可以使用BrowserWindow构造函数中的sandbox: true首选项按进程启用渲染器沙盒。

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

Enabling the sandbox globally全局启用沙盒

If you want to force sandboxing for all renderers, you can also use the app.enableSandbox API. 如果要强制所有渲染器使用沙箱,还可以使用app.enableSandbox API。Note that this API has to be called before the app's ready event.请注意,必须在应用程序ready事件之前调用此API。

// main.js
app.enableSandbox()
app.whenReady().then(() => {
// no need to pass `sandbox: true` since `app.enableSandbox()` was called.
const win = new BrowserWindow()
win.loadURL('https://google.com')
})

Disabling Chromium's sandbox (testing only)禁用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). 您还可以使用--no-sandbox CLI标志完全禁用Chromium的沙盒,这将禁用所有进程(包括实用程序进程)的沙盒。We highly recommend that you only use this flag for testing purposes, and never in production.我们强烈建议您仅将此标志用于测试目的,绝不在生产中使用。

Note that the sandbox: true option will still disable the renderer's Node.js environment.请注意,sandbox:true选项仍将禁用渲染器的Node.js环境。

A note on rendering untrusted content关于呈现不可信内容的注意事项

Rendering untrusted content in Electron is still somewhat uncharted territory, though some apps are finding success (e.g. Beaker Browser). 在Electron版中呈现不受信任的内容仍然是一个未知数,尽管一些应用程序正在取得成功(如比克浏览器)。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:目标是在沙盒内容的安全性方面尽可能接近Chrome,但最终由于一些基本问题,我们将始终落后:

  1. 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.我们尽最大努力利用我们所拥有的一切,从铬中继承一切,并迅速应对安全问题,但如果没有铬能够提供的资源,Electron就无法像铬一样安全。
  2. 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. Chrome中的一些安全功能(如安全浏览和证书透明性)需要集中式授权和专用服务器,这两者都与Electron项目的目标背道而驰。As such, we disable those features in Electron, at the cost of the associated security they would otherwise bring.因此,我们禁用了Electron中的这些功能,代价是它们会带来的相关安全性。
  3. There is only one Chromium, whereas there are many thousands of apps built on Electron, all of which behave slightly differently. 只有一个Chromium,而有数千个基于Electron的应用程序,它们的行为都略有不同。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.考虑到这些差异可能会产生巨大的可能性空间,并使确保平台在异常使用情况下的安全性具有挑战性。
  4. 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.我们无法直接向用户推送安全更新,因此我们依赖应用程序供应商升级其应用程序的基础版本,以便安全更新能够到达用户。

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. 虽然我们尽最大努力将Chromium安全修复程序向后移植到旧版本的Electron,但我们不能保证每个修复程序都会被向后移植。Your best chance at staying secure is to be on the latest stable version of Electron.保持安全的最佳机会是使用最新稳定版本的Electron。