Electron 進程沙盒化

2023-02-16 17:14 更新

Chromium的一個關鍵安全特性是,進程可以在沙盒中執(zhí)行。 沙盒通過限制對大多數(shù)系統(tǒng)資源的訪問來減少惡意代碼可能造成的傷害 — 沙盒化的進程只能自由使用CPU周期和內(nèi)存。 為了執(zhí)行需要額外權限的操作,沙盒處的進程通過專用通信渠道將任務下放給更大權限的進程。

在Chromium中,沙盒化應用于主進程以外的大多數(shù)進程。 其中包括渲染器進程,以及功能性進程,如音頻服務、GPU 服務和網(wǎng)絡服務。

查閱Chromium的 沙箱設計文檔 了解更多信息。

從 Electron 20 開始,無需任何進一步配置即可為渲染器進程啟用沙箱。

Electron 中的沙盒行為?

在 Electron 中沙盒進程 大部分地 表現(xiàn)都與 Chromium 差不多, 但因為介面是 Node.js 的關系 Electron 有一些額外的概念需要考慮。

渲染器進程?

當 Electron 中的渲染進程被沙盒化時,它們的行為與常規(guī) Chrome 渲染器一樣。 一個沙盒化的渲染器不會有一個 Node.js 環(huán)境。

因此,在沙盒中,渲染進程只能透過 進程間通訊 (inter-process communication, IPC) 委派任務給主進程的方式, 來執(zhí)行需權限的任務 (例如:文件系統(tǒng)交互,對系統(tǒng)進行更改或生成子進程) 。

Preload 腳本

為了讓渲染進程能與主進程通信,附屬于沙盒化的渲染進程的 preload 腳本中仍可使用一部分以 Polyfill 形式實現(xiàn)的 Node.js API。 有一個與 Node 中類似的 require 函數(shù)提供了出來,但只能載入 Electron 和 Node 內(nèi)置模塊的一個子集:

此外,以下 Node.js 基礎對象也填充到了 preload 腳本的全局上下文中:

require 函數(shù)只是一個功能有限的 Ployfill 實現(xiàn),并不支持把 preload 腳本拆成多個文件然后作為 CommonJS 模塊 來加載。 若需要拆分 preload 腳本的代碼,可以使用 webpack 或 Parcel 等打包工具。

注意,因為 preload 腳本的運行環(huán)境本質(zhì)上比沙盒化渲染進程的擁有更高的特權,除非開啟了 ?contextIsolation?,否則高特權的 API 仍有可能被泄漏給渲染進程中的不信任代碼。

配置沙盒

對于大多數(shù)應用程序,沙盒是最佳選擇。在某些與沙箱不兼容的用例中(例如,在渲染器中使用本機節(jié)點模塊時),可以為特定進程禁用沙箱。這會帶來安全風險,尤其是在非沙盒進程中存在任何不受信任的代碼或內(nèi)容時。

為單個進程禁用沙盒

在 Electron 中,可以在每個進程的基礎上使用 ?BrowserWindow? 構造函數(shù)中的 ?sandbox: false? 首選項禁用渲染器沙箱。

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

只要在渲染器中啟用 Node.js 集成,沙盒也會被禁用。這可以通過帶有 ?nodeIntegration: true? 標志的 BrowserWindow 構造函數(shù)來完成。

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

全局啟用沙盒

你也可以調(diào)用 ?app.enableSandbox? API 來強制沙盒化所有渲染器。 注意,此 API 必須在應用的 ready 事件之前調(diào)用。

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? 命令行參數(shù)來完全禁用 Chromium 的沙盒功能,這會使沙盒對所有進程失效(包括工具進程)。 我們強烈建議你只針對測試用途開啟此標志,并且 永遠 不要用于生產(chǎn)環(huán)境。

注意,sandbox: true 選項也會同時禁用渲染進程中的 Node.js 環(huán)境。

渲染不可信內(nèi)容的注意事項

盡管已經(jīng)有一些成功案例(例如 Beaker 瀏覽器),但在 Electron 中渲染不受信任的內(nèi)容仍有未知的風險。 我們的目標是盡可能達到與 Chrome 中沙盒化的內(nèi)容一樣的安全性,但由于一些現(xiàn)實因素還沒法做到:

  1. 我們不像 Chromium 團隊那樣在產(chǎn)品安全方面有專屬的資源與專業(yè)知識。 雖然已經(jīng)盡可能地繼承 Chromium 中的一切,并且盡快響應安全問題,但缺少 Chromium 可調(diào)動的那些資源,我們做不到和它一樣安全。
  2. Chrome 的一些安全特性(例如安全瀏覽和證書透明度)依賴于中心化授權和專屬服務器,這些都超出了 Electron 項目的目標。 因此我們在 Electron 中禁用了它們,同時也損失了它們帶來的安全性。
  3. Chromium 只有一個,但基于 Electron 構建的應用卻成千上萬,并且千差萬別。 這些差異帶來了太多的可能性,很難在各種特殊的應用場景下都保證平臺的安全。
  4. 我們沒法向終端用戶直接推送安全更新,只能靠應用供應商更新依賴的 Electron 版本,來讓更新覆蓋到用戶。

雖然我們會盡可能將 Chromium 的安全修復應用到老版本的 Electron 中,但沒法保證每一個修復都能移植過去。 為了保證安全,最好的辦法還是始終使用最新的穩(wěn)定版 Electron。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號