進程沙箱
Chromium 中的一個關鍵安全功能是,進程可以在沙箱內執行。沙箱透過限制對大多數系統資源的存取來限制惡意程式碼可能造成的危害 — 沙箱進程只能自由使用 CPU 週期和記憶體。為了執行需要額外權限的操作,沙箱進程使用專用的通訊通道將任務委派給權限更高的進程。
在 Chromium 中,沙箱適用於大多數進程,主進程除外。這包括渲染器進程,以及工具進程,例如音訊服務、GPU 服務和網路服務。
請參閱 Chromium 的 沙箱設計文件 以取得更多資訊。
從 Electron 20 開始,沙箱已為渲染器進程啟用,無需任何進一步設定。如果您想為進程停用沙箱,請參閱停用單一進程的沙箱章節。
Electron 中的沙箱行為
Electron 中的沙箱進程的行為大致上與 Chromium 中的行為相同,但 Electron 有一些額外的概念需要考慮,因為它與 Node.js 介接。
渲染器進程
當 Electron 中的渲染器進程被沙箱化時,它們的行為方式與一般的 Chrome 渲染器相同。沙箱渲染器不會初始化 Node.js 環境。
因此,當沙箱啟用時,渲染器進程只能透過將這些任務委派給主進程,透過進程間通訊 (IPC) 來執行特權任務(例如與檔案系統互動、變更系統或產生子進程)。
有關進程間通訊的更多資訊,請查看我們的 IPC 指南。
預載腳本
為了允許渲染器進程與主進程通訊,附加到沙箱渲染器的預載腳本仍然可以使用 polyfill 的 Node.js API 子集。公開了類似於 Node 的 require
模組的 require
函數,但只能匯入 Electron 和 Node 的內建模組的子集
electron
(以下渲染器進程模組:contextBridge
、crashReporter
、ipcRenderer
、nativeImage
、webFrame
、webUtils
)events
timers
url
node: imports 也受支援
此外,預載腳本也將某些 Node.js 原始類型 polyfill 為全域變數
由於 require
函數是一個功能有限的 polyfill,您將無法使用 CommonJS 模組 將您的預載腳本分成多個檔案。如果您需要拆分您的預載程式碼,請使用打包器,例如 webpack 或 Parcel。
請注意,由於呈現給 preload
腳本的環境比沙箱渲染器的環境權限高得多,因此除非啟用 contextIsolation
,否則仍然有可能將特權 API 洩露給在渲染器進程中執行的不受信任的程式碼。
設定沙箱
對於大多數應用程式來說,沙箱是最佳選擇。在某些與沙箱不相容的使用案例中(例如,在渲染器中使用原生 node 模組時),可以為特定進程停用沙箱。這會帶來安全風險,尤其是當不受信任的程式碼或內容出現在未沙箱化的進程中時。
停用單一進程的沙箱
在 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 Browser)。我們的目標是在沙箱內容的安全性方面盡可能接近 Chrome,但最終我們將始終落後,原因在於一些基本問題
- 我們沒有 Chromium 所擁有的專門資源或專業知識來應用於其產品的安全性。我們盡力利用我們所擁有的資源,繼承我們可以從 Chromium 繼承的一切,並快速回應安全問題,但如果沒有 Chromium 能夠投入的資源,Electron 無法像 Chromium 一樣安全。
- Chrome 中的某些安全功能(例如 Safe Browsing 和憑證透明度)需要中央授權機構和專用伺服器,這兩者都與 Electron 專案的目標背道而馳。因此,我們在 Electron 中停用了這些功能,但代價是它們本應帶來的相關安全性。
- 只有一個 Chromium,而有數千個基於 Electron 建構的應用程式,所有這些應用程式的行為都略有不同。考量到這些差異可能會產生巨大的可能性空間,並使確保平台在不常見使用案例中的安全性變得具有挑戰性。
- 我們無法直接向使用者推送安全更新,因此我們依賴應用程式供應商來升級其應用程式底層的 Electron 版本,以便安全更新能夠到達使用者。
雖然我們盡最大努力將 Chromium 安全修復程式向後移植到舊版本的 Electron,但我們不保證每個修復程式都會向後移植。保持安全的最佳機會是使用最新穩定版本的 Electron。