程序沙盒
Chromium 的一個重要安全功能是程序可以在沙盒中執行。沙盒透過限制對大多數系統資源的存取來限制惡意程式碼可能造成的危害 — 沙盒程序只能自由使用 CPU 週期和記憶體。為了執行需要額外權限的操作,沙盒程序會使用專用的通訊通道將任務委派給權限較高的程序。
在 Chromium 中,沙盒適用於除了主程序之外的大多數程序。這包括渲染器程序,以及諸如音訊服務、GPU 服務和網路服務等公用程式程序。
有關更多資訊,請參閱 Chromium 的沙盒設計文件。
從 Electron 20 開始,沙盒已針對渲染器程序啟用,無需任何其他配置。 如果您要針對單個程序禁用沙盒,請參閱針對單個程序禁用沙盒章節。
Electron 中的沙盒行為
Electron 中沙盒程序的行為與 Chromium 的程序行為大致相同,但 Electron 有一些額外的概念需要考慮,因為它與 Node.js 介面。
渲染器程序
當 Electron 中的渲染器程序被沙盒化時,它們的行為方式與常規的 Chrome 渲染器相同。沙盒化的渲染器不會初始化 Node.js 環境。
因此,當啟用沙盒時,渲染器程序只能透過將這些任務透過跨程序通訊 (IPC) 委派給主程序來執行特權任務 (例如與檔案系統互動、更改系統或產生子程序)。
有關跨程序通訊的更多資訊,請查看我們的IPC 指南。
預加載腳本
為了讓渲染器程序可以與主程序通訊,附加到沙盒渲染器的預加載腳本仍然可以使用 Node.js API 的 polyfilled 子集。 會公開類似於 Node 的 require
模組的 require
函式,但只能匯入 Electron 和 Node 的內建模組的子集
electron
(以下渲染器程序模組:contextBridge
、crashReporter
、ipcRenderer
、nativeImage
、webFrame
、webUtils
)events
timers
url
也支援node: 匯入
此外,預加載腳本還會將某些 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 瀏覽器)。 我們的目標是在沙盒內容的安全性方面盡可能接近 Chrome,但由於一些基本問題,我們最終將永遠落後
- 我們沒有 Chromium 用於其產品安全性的專用資源或專業知識。 我們會盡力利用我們所擁有的資源、繼承我們能從 Chromium 繼承的一切,並快速回應安全問題,但如果沒有 Chromium 能夠投入的資源,Electron 無法像 Chromium 那樣安全。
- Chrome 中的某些安全功能 (例如安全瀏覽和憑證透明度) 需要中央機構和專用伺服器,這兩者都與 Electron 專案的目標背道而馳。 因此,我們會在 Electron 中停用這些功能,代價是它們原本會帶來的相關安全性。
- 只有一個 Chromium,但有數千個基於 Electron 建置的應用程式,它們的行為都略有不同。 考慮到這些差異可能會產生巨大的可能性空間,並使確保在不尋常的用例中平台安全性具有挑戰性。
- 我們無法直接向使用者推送安全更新,因此我們依賴應用程式供應商來升級其應用程式底層的 Electron 版本,以便安全更新可以觸及使用者。
儘管我們會盡最大努力將 Chromium 安全修復程式反向移植到舊版本的 Electron 中,但我們並不保證每個修復程式都會被反向移植。 保持安全的最佳方法是使用最新穩定的 Electron 版本。