跳到主要内容

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:// 协议页面可以使用 service worker
  • 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
}
)

您可以使用 fuses 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”。

您可以在此处查看当前模式。