跳到主要内容

Electron Fuses

打包时特性切换

什么是熔断器 (fuses)?

对于 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 将无法按预期运行,因为它依赖于此环境变量才能运行。作为替代,我们建议您使用 Utility Processes,它适用于许多需要独立 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 和 Windows 上启用了一个实验性功能,它在加载 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 快照文件。 当此熔断器启用时,浏览器进程将其 V8 快照使用名为 browser_v8_context_snapshot.bin 的文件。 其他进程将使用它们通常使用的 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

困难方法

快速词汇表

  • 熔断器线 (Fuse Wire):Electron 二进制文件中的字节序列,用于控制熔断器
  • 哨兵 (Sentinel):可用于定位熔断器线的静态已知字节序列
  • 熔断器模式 (Fuse Schema):熔断器线的格式/允许值

手动翻转熔断器需要编辑 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”。

您可以在这里查看当前模式。