跳到主要內容

Electron 保險絲

封裝時間功能切換

什麼是保險絲?

對於 Electron 的一部分功能,停用整個應用程式的某些功能是有意義的。例如,99% 的應用程式不會使用 ELECTRON_RUN_AS_NODE,這些應用程式希望能夠發布一個無法使用該功能的二進位檔。我們也不希望 Electron 消費者從原始碼建構 Electron,因為這既是巨大的技術挑戰,也需要付出大量時間和金錢成本。

保險絲是這個問題的解決方案,在高階層面上,它們是 Electron 二進位檔中的「魔法位」,可以在封裝您的 Electron 應用程式時切換,以啟用/停用某些功能/限制。由於它們是在您對應用程式進行程式碼簽署之前的封裝時間切換的,因此作業系統負責確保這些位不會透過作業系統層級的程式碼簽署驗證(Gatekeeper / App Locker)翻轉回去。

目前的保險絲

runAsNode

預設值:已啟用

@electron/fuses:FuseV1Options.RunAsNode

runAsNode 保險絲會切換是否接受 ELECTRON_RUN_AS_NODE 環境變數。請注意,如果停用了此保險絲,則主要程序中的 process.fork 將無法如預期運作,因為它依賴此環境變數才能運作。相反地,我們建議您使用 實用程序,它們適用於許多需要獨立 Node.js 程序的情況(例如 Sqlite 伺服器程序或類似情況)。

cookieEncryption

預設值:已停用

@electron/fuses:FuseV1Options.EnableCookieEncryption

cookieEncryption 保險絲會切換是否使用作業系統層級的加密金鑰來加密磁碟上的 Cookie 儲存區。預設情況下,Chromium 用來儲存 Cookie 的 sqlite 資料庫會以純文字儲存值。如果您希望確保應用程式的 Cookie 以與 Chrome 相同的方式加密,則應啟用此保險絲。請注意,這是一個單向轉換,如果您啟用此保險絲,現有未加密的 Cookie 將在寫入時加密,但如果您隨後再次停用該保險絲,您的 Cookie 儲存區實際上將會損壞且無用。大多數應用程式都可以安全地啟用此保險絲。

nodeOptions

預設值:已啟用

@electron/fuses:FuseV1Options.EnableNodeOptionsEnvironmentVariable

nodeOptions 保險絲會切換是否接受 NODE_OPTIONSNODE_EXTRA_CA_CERTS 環境變數。NODE_OPTIONS 環境變數可用於將各種自訂選項傳遞給 Node.js 執行階段,通常不會在生產中的應用程式中使用。大多數應用程式都可以安全地停用此保險絲。

nodeCliInspect

預設值:已啟用

@electron/fuses:FuseV1Options.EnableNodeCliInspectArguments

nodeCliInspect 保險絲會切換是否接受 --inspect--inspect-brk 等旗標。停用時,它還會確保 SIGUSR1 訊號不會初始化主要程序檢查器。大多數應用程式都可以安全地停用此保險絲。

embeddedAsarIntegrityValidation

預設值:已停用

@electron/fuses:FuseV1Options.EnableEmbeddedAsarIntegrityValidation

embeddedAsarIntegrityValidation 保險絲會切換 macOS 上的一個實驗性功能,該功能會在載入時驗證 app.asar 檔案的內容。此功能的設計目的是將效能影響降至最低,但可能會稍微減慢從 app.asar 封存檔內部讀取檔案的速度。

有關如何使用 asar 完整性驗證的更多資訊,請閱讀 Asar 完整性 文件。

onlyLoadAppFromAsar

預設值:已停用

@electron/fuses:FuseV1Options.OnlyLoadAppFromAsar

onlyLoadAppFromAsar 保險絲會變更 Electron 用來尋找應用程式程式碼的搜尋系統。預設情況下,Electron 將按以下順序搜尋:app.asar -> app -> default_app.asar。啟用此保險絲後,搜尋順序將變為單個項目 app.asar,從而確保與 embeddedAsarIntegrityValidation 保險絲結合使用時,不可能載入未經驗證的程式碼。

loadBrowserProcessSpecificV8Snapshot

預設值:已停用

@electron/fuses:FuseV1Options.LoadBrowserProcessSpecificV8Snapshot

loadBrowserProcessSpecificV8Snapshot 保險絲會變更用於瀏覽器程序的 V8 快照檔案。預設情況下,Electron 的程序將全部使用相同的 V8 快照檔案。啟用此保險絲後,瀏覽器程序會使用名為 browser_v8_context_snapshot.bin 的檔案作為其 V8 快照。其他程序將使用它們通常使用的 V8 快照檔案。

V8 快照可用於提高應用程式啟動效能。V8 允許您取得已初始化堆積的快照,然後將它們載回,以避免初始化堆積的成本。

為渲染程序和主要程序使用單獨的快照可以提高安全性,尤其是確保渲染器不使用啟用 nodeIntegration 的快照。請參閱 #35170 以了解詳細資訊。

grantFileProtocolExtraPrivileges

預設值:已啟用

@electron/fuses:FuseV1Options.GrantFileProtocolExtraPrivileges

grantFileProtocolExtraPrivileges 保險絲會變更是否向從 file:// 通訊協定載入的頁面授予超出傳統 Web 瀏覽器中會接收的權限。此行為是 Electron 早期版本中 Electron 應用程式的核心,但現在不再需要,因為應用程式現在應該從 自訂通訊協定供應本機檔案。如果您不是從 file:// 供應頁面,則應該停用此保險絲。

此保險絲授予 file:// 通訊協定的額外權限在下面未完全記載

  • file:// 通訊協定頁面可以使用 fetch 來透過 file:// 載入其他資源
  • file:// 通訊協定頁面可以使用服務工作人員
  • file:// 通訊協定頁面具有對也在 file:// 通訊協定上執行的子框架的通用存取權,無論沙箱設定為何

我如何翻轉保險絲?

簡單的方法

我們製作了一個方便的模組 @electron/fuses,讓翻轉這些保險絲變得容易。查看該模組的 README,以了解有關使用方式和潛在錯誤案例的更多詳細資訊。

const { flipFuses, FuseVersion, FuseV1Options } = require('@electron/fuses')

flipFuses(
// Path to electron
require('electron'),
// Fuses to flip
{
version: FuseVersion.V1,
[FuseV1Options.RunAsNode]: false
}
)

您可以使用保險絲 CLI 驗證保險絲是否已翻轉,或檢查任意 Electron 應用程式的保險絲狀態。

npx @electron/fuses read --app /Applications/Foo.app

困難的方法

快速詞彙表

  • 保險絲線:Electron 二進位檔中用於控制保險絲的位元組序列
  • 哨兵:您可以用来尋找保險絲線的靜態已知位元組序列
  • 保險絲架構:保險絲線的格式/允許的值

手動翻轉保險絲需要編輯 Electron 二進位檔,並修改保險絲線,使其成為代表您想要的保險絲狀態的位元組序列。

在 Electron 二進位檔中的某個地方,將會出現如下所示的位元組序列

| ...binary | sentinel_bytes | fuse_version | fuse_wire_length | fuse_wire | ...binary |
  • sentinel_bytes 始終是這個確切的字串 dL7pKGdnNz796PbbjQWNKmHXBZaB9tsX
  • fuse_version 是一個單一位元組,其無號整數值代表熔絲結構的版本。
  • fuse_wire_length 是一個單一位元組,其無號整數值代表以下熔絲線中的熔絲數量。
  • fuse_wire 是一個 N 個位元組的序列,每個位元組代表一個熔絲及其狀態。
    • "0" (0x30) 表示熔絲已停用。
    • "1" (0x31) 表示熔絲已啟用。
    • "r" (0x72) 表示熔絲已被移除,將位元組變更為 1 或 0 皆無效。

要翻轉熔絲,您需要找到它在熔絲線中的位置,並根據您想要的狀態將其變更為 "0" 或 "1"。

您可以在這裡查看目前的結構。