进程沙盒化
1027字约3分钟
2024-12-09
进程沙盒化
Chromium 的一个关键安全特性是,进程可以在沙盒中执行。 沙盒通过限制对大多数系统资源的访问来减少恶意代码可能造成的伤害 — 沙盒化的进程只能自由使用 CPU 周期和内存。 为了执行需要额外权限的操作,沙盒处的进程通过专用通信渠道将任务下放给更大权限的进程。
在 Chromium 中,沙盒化应用于主进程以外的大多数进程。 其中包括渲染器进程,以及功能性进程,如音频服务、GPU 服务和网络服务。
注意
从 Electron 20
开始,渲染进程默认启用了沙盒,无需进一步配置。 如果你想禁用某个进程的沙盒,请参阅为单个进程禁用沙盒部分。
Electron 中的沙盒行为
在 Electron
中沙盒进程 大部分地 表现都与 Chromium
差不多, 但因为介面是 Node.js
的关系 Electron
有一些额外的概念需要考虑。
渲染器进程
当 Electron 中的渲染进程被沙盒化时,它们的行为与常规 Chrome 渲染器一样。 一个沙盒化的渲染器不会有一个 Node.js 环境。
因此,在沙盒中,渲染进程只能透过 进程间通讯 (inter-process communication, IPC) 委派任务给主进程的方式, 来执行需权限的任务 (例如:文件系统交互,对系统进行更改或生成子进程) 。
Preload 脚本
为了让渲染进程能与主进程通信,附属于沙盒化的渲染进程的 preload
脚本中仍可使用一部分以 Polyfill
形式实现的 Node.js API
。 有一个与 Node
中类似的 require
函数提供了出来,但只能载入 Electron
和 Node
内置模块的一个子集:
electron
(以下是渲染进程的模块:contextBridge
,crashReporter
,ipcRenderer
,nativeImage
,webFrame
,webUtils
)events
timers
url
Node.js
中的 import
方法也是被支持的:
- events
- timers
- url
此外,以下 Node.js
基础对象也填充到了 preload
脚本的全局上下文中:
Buffer
process
clearImmediate
setImmediate
注意
require
函数只是一个功能有限的 Ployfill
实现,并不支持把 preload 脚本拆成多个文件然后作为 CommonJS
模块 来加载。 若需要拆分 preload
脚本的代码,可以使用 webpack
或 Parcel
等打包工具。
配置沙盒
对于大多数应用程序来说,沙盒是最佳选择。 在某些与沙盒不兼容的使用情况下(例如,在渲染器中使用原生的 Node.js 模块时),可以禁用特定进程的沙盒。 但这会带来安全风险,特别是当未受信任的代码或内容存在于未沙盒化的进程中时。
为单个进程禁用沙盒
在 Electron 中,可以使用 BrowserWindow
构造函数中的 sandbox: false
选项禁用每个进程的渲染器沙盒。
app.whenReady().then(() => {
const win = new BrowserWindow({
webPreferences: {
sandbox: false
}
})
win.loadURL('https://google.com')
})
在渲染器中启用 nodeIntegration
时,沙盒也会被禁用。 可以通过在 BrowserWindow
构造函数中添加 nodeIntegration: true
标志的来实现。
app.whenReady().then(() => {
const win = new BrowserWindow({
webPreferences: {
nodeIntegration: true
}
})
win.loadURL('https://google.com')
})
全局启用沙盒
如果想全局启用渲染进程的沙盒设置,你可以调用 app.enableSandbox()
方法。 这将启用所有渲染器的沙盒。此 API 必须在应用的 whenReady
事件之前调用。
app.enableSandbox()
app.whenReady().then(() => }
// 因为调用了app.enableSandbox(),所以任何sandbox:false的调用都会被覆盖。
const win = new BrowserWindow()
win.loadURL('https://google.com')
})
禁用 Chromium 的沙盒(仅测试)
您还可以使用 --no-sandbox
CLI标志完全禁用 Chromium 的沙箱,这将禁用所有进程(包括实用程序进程)的沙箱。 我们强烈建议你只针对测试用途开启此标志,并且永远不要用于生产环境。
注意
注意,sandbox: true
选项也会同时禁用渲染进程中的 Node.js
环境。