Saltar al contenido principal

Electron Fuses

Alterna característica en tiempo de empaquetado

¿Qué son los fusibles?

Para un subconjunto de funcionalidad de Electron tiene sentido deshabilitar ciertas características para una aplicación entera. Por ejemplo, el 99% de las aplicaciones no hacen uso de ELECTRON_RUN_AS_NODE, estas aplicaciones quiere ser capaz de enviar un binario que sea incapaz de usar esa característica. Además no queremos que los consumidores de Electron construyan Electron a partir de la fuente, ya que ese es un desafío técnico masivo y tiene un alto costo tanto en tiempo como en dinero.

Los fusibles son la solución a este problema, en un alto nivel son "bits mágicos" en el binario de Electron que se pueden voltear cuando empaca su aplicación Electron para habilitar / deshabilitar ciertas características / restricciones. Debido a que son volteados en tiempo de empaquetado antes de que el código firme la aplicación, el sistema operativo se hace responsable de asegurar que esos bits no son volteados de nuevo a través de la validación de firma de código a nivel de sistema operativo (Gatekeeper / App Locker).

Current Fuses

runAsNode

Default: Enabled

@electron/fuses: FuseV1Options.RunAsNode

The runAsNode fuse toggles whether the ELECTRON_RUN_AS_NODE environment variable is respected or not. Please note that if this fuse is disabled then process.fork in the main process will not function as expected as it depends on this environment variable to function. Instead, we recommend that you use Utility Processes, which work for many use cases where you need a standalone Node.js process (like a Sqlite server process or similar scenarios).

cookieEncryption

Default: Disabled

@electron/fuses: FuseV1Options.EnableCookieEncryption

The cookieEncryption fuse toggles whether the cookie store on disk is encrypted using OS level cryptography keys. By default the sqlite database that Chromium uses to store cookies stores the values in plaintext. If you wish to ensure your apps cookies are encrypted in the same way Chrome does then you should enable this fuse. Please note it is a one-way transition, if you enable this fuse existing unencrypted cookies will be encrypted-on-write but if you then disable the fuse again your cookie store will effectively be corrupt and useless. La mayoría de las apps pueden habilitar este fusible de forma segura.

nodeOptions

Default: Enabled

@electron/fuses: FuseV1Options.EnableNodeOptionsEnvironmentVariable

The nodeOptions fuse toggles whether the NODE_OPTIONS and NODE_EXTRA_CA_CERTS environment variables are respected. The NODE_OPTIONS environment variable can be used to pass all kinds of custom options to the Node.js runtime and isn't typically used by apps in production. La mayoría de las aplicaciones pueden desactivar con seguridad este fusible.

nodeCliInspect

Default: Enabled

@electron/fuses: FuseV1Options.EnableNodeCliInspectArguments

The nodeCliInspect fuse toggles whether the --inspect, --inspect-brk, etc. flags are respected or not. When disabled it also ensures that SIGUSR1 signal does not initialize the main process inspector. La mayoría de las aplicaciones pueden desactivar con seguridad este fusible.

embeddedAsarIntegrityValidation

Default: Disabled

@electron/fuses: FuseV1Options.EnableEmbeddedAsarIntegrityValidation

The embeddedAsarIntegrityValidation fuse toggles an experimental feature on macOS that validates the content of the app.asar file when it is loaded. This feature is designed to have a minimal performance impact but may marginally slow down file reads from inside the app.asar archive.

For more information on how to use asar integrity validation please read the Asar Integrity documentation.

onlyLoadAppFromAsar

Default: Disabled

@electron/fuses: FuseV1Options.OnlyLoadAppFromAsar

The onlyLoadAppFromAsar fuse changes the search system that Electron uses to locate your app code. Por defecto Electron buscará en el siguiente orden app.asar -> app -> default_app.asar. When this fuse is enabled the search order becomes a single entry app.asar thus ensuring that when combined with the embeddedAsarIntegrityValidation fuse it is impossible to load non-validated code.

loadBrowserProcessSpecificV8Snapshot

Default: Disabled

@electron/fuses: FuseV1Options.LoadBrowserProcessSpecificV8Snapshot

The loadBrowserProcessSpecificV8Snapshot fuse changes which V8 snapshot file is used for the browser process. By default Electron's processes will all use the same V8 snapshot file. When this fuse is enabled the browser process uses the file called browser_v8_context_snapshot.bin for its V8 snapshot. The other processes will use the V8 snapshot file that they normally do.

V8 snapshots can be useful to improve app startup performance. V8 lets you take snapshots of initialized heaps and then load them back in to avoid the cost of initializing the heap.

Using separate snapshots for renderer processes and the main process can improve security, especially to make sure that the renderer doesn't use a snapshot with nodeIntegration enabled. See #35170 for details.

grantFileProtocolExtraPrivileges

Default: Enabled

@electron/fuses: FuseV1Options.GrantFileProtocolExtraPrivileges

The grantFileProtocolExtraPrivileges fuse changes whether pages loaded from the file:// protocol are given privileges beyond what they would receive in a traditional web browser. This behavior was core to Electron apps in original versions of Electron but is no longer required as apps should be serving local files from custom protocols now instead. If you aren't serving pages from file:// you should disable this fuse.

The extra privileges granted to the file:// protocol by this fuse are incompletely documented below:

  • file:// protocol pages can use fetch to load other assets over file://
  • file:// protocol pages can use service workers
  • file:// protocol pages have universal access granted to child frames also running on file:// protocols regardless of sandbox settings

¿Cómo voltear los fusibles?

La forma fácil

Hemos creado a un módulo práctico, @electron/fuses, para facilitar el cambio de estos fusibles. Revisa el README del módulo para más detalles sobre uso y los casos de errores potenciales.

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

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

You can validate the fuses have been flipped or check the fuse status of an arbitrary Electron app using the fuses CLI.

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

La forma difícil

Glosario Rápido

  • Fuse Wire: Una secuencia de bytes en el binario de Electron usados para controlar los fusibles
  • Sentinel: Una secuencia estática conocida de bytes que puedes usar para localizar el cable del fusible
  • Fuse Schema: El formato / valores permitidos para el cable de fusible

Para voltear los fusibles manualmente, es necesario editar el binario de Electron y modificar el cable del fusible para que sea la secuencia de bytes que represente el estado de los fusibles que desea.

En algún lugar en el binario de Electron habrá una secuencia de bytes que se verán así:

| ...binary | sentinel_bytes | fuse_version | fuse_wire_length | fuse_wire | ...binary |
  • sentinel_bytes siempre es esta cadena exacta dL7pKGdnNz796PbbjQWNKmHXBZaB9tsX
  • fuse_version es un solo byte cuyo valor entero sin signo representa la versión del esquema de fusible
  • fuse_wire_length es un solo byte cuyo valor entero sin signo representa el numero de fusibles en el siguiente cable de fusible
  • fuse_wire es una secuencia de N bytes, cada byte representa un solo fusible y su estado.
    • "0" (0x30) indica que el fusible esta desactivado
    • "1" (0x31) indica que el fusible esta activado
    • "r" (0x72) indica que el fusible a sido eliminado y cambiar el byte 1 o 0 no tendrá efecto.

Para voltear un fusible busque su posición en el cable del fusible y cámbielo a "0" o "1" dependiendo del estado que desee.

Puede ver el esquema actual aquí.