Aller au contenu principal

Les Fuses d'Electron

Activation/désactivation de fonctionnalités au moment du packaging

Que sont les fuses ?

Si une application n'utilise qu'un sous-ensemble de fonctionnalités d'Electron, il semble logique de désactiver certaines fonctionnalités pour l'ensemble de celle-ci. Par exemple, 99% des applications n'utilisent pas ELECTRON_RUN_AS_NODE, leurs concepteurs veulent être en mesure de livrer un exécutable qui n'utilise pas cette fonctionnalité. Nous ne voulons pas non plus que cela implique que les utilisateurs d'Electron doivent génèrer leur version d'Electron à partir des sources car ce serait à la fois un défi technique énorme et aurait un coût élevé que ce soit en temps ou en argent.

Les fuses représentent la solution à ce problème, à un haut niveau, ils sont des "bits magiques" dans l'exécutable d'Electron qui peuvent être activés ou non au moment du packaging de votre application Electron pour activer ou désactiver certaines fonctionnalités ou restrictions. Comme ils sont basculés au moment du packaging et donc avant que vous ne signiez votre application, c'est à l'OS que revient la responsabilité de s'assurer que ces bits n'ont pas été désactivés via la validation du code du système d'exploitation (Gatekeeper / App Locker).

Fuses actuels

runAsNode

Par défaut: Activé

@electron/fuses: FuseV1Options.RunAsNode

Le fuse runAsNode acitve ou désactive le respect de la variable d'environnement ELECTRON_RUN_AS_NODE. Veuillez noter que si ce fuse est désactivé, process.fork dans le processus principal ne fonctionnera pas comme prévu puisqu'il dépend de la dite variable pour fonctionner. Nous vous recommandons plutôt d’utiliser Utility Processes, qui fonctionne pour de nombreux cas d’utilisation où vous avez besoin d’un processus Node.js autonome (comme un processus serveur Sqlite ou des scénarios similaires).

cookieEncryption

Par défaut: Désactivé

@electron/fuses: FuseV1Options.EnableCookieEncryption

Le fuse cookieEncryption active ou désactive le cryptage du magasin de cookies sur le disque à l’aide de clés de chiffrement au niveau du système d’exploitation. Par défaut, la base de données sqlite utilisée par Chromium pour stocker les cookies stocke les valeurs en texte brut. Si vous souhaitez vous assurer que les cookies de vos applications sont cryptés de la même manière que Chrome, vous devez activer ce fuse. Veuillez noter que c'est une transition à sens unique, Si vous activez ce fuse les cookies non chiffrés existants seront chiffrés en écriture, mais si vous désactivez le fuse à nouveau, votre stockage de cookies sera vraiment corrompu et inutile. La plupart des applications peuvent activer ce fuse en toute sécurité.

nodeOptions

Par défaut: Activé

@electron/fuses: FuseV1Options.EnableNodeOptionsEnvironmentVariable

Le fuse nodeOptions permet de basculer entre les variables d’environnement NODE_OPTIONS et NODE_EXTRA_CA_CERTS. La variable d’environnement NODE_OPTIONS peut être utilisée pour transmettre toutes sortes d’options personnalisées à l’environnement d’exécution de Node.js et n’est généralement pas utilisée par les applications en production. La plupart des applications peuvent désactiver ce fuse en toute sécurité.

nodeCliInspect

Par défaut: Activé

@electron/fuses: FuseV1Options.EnableNodeCliInspectArguments

Le fuse nodeCliInspect active ou désactive le respect des indicateurs --inspect, --inspect-brk, etc. Lorsqu’il est désactivé, il garantit également que le signal SIGUSR1 n’initialise pas l’inspecteur de processus principal. La plupart des applications peuvent désactiver ce fuse en toute sécurité.

embeddedAsarIntegrityValidation

Par défaut: Désactivé

@electron/fuses: FuseV1Options.EnableEmbeddedAsarIntegrityValidation

Le fuse embeddedAsarIntegrityValidation active ou désactive une fonctionnalité expérimentale sur macOS validant le contenu du fichier app.asar lorsque celui-ci est chargé. Cette fonctionnalité est conçue pour avoir un impact minimal sur les performances, mais peut ralentir légèrement les lectures de fichiers à partir de l’archive app.asar .

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

onlyLoadAppFromAsar

Par défaut: Désactivé

@electron/fuses: FuseV1Options.OnlyLoadAppFromAsar

Le fuse onlyLoadAppFromAsar modifie le système de recherche qu’Electron utilise pour localiser le code de votre application. Par défaut, la recherche d'Electron s'effectuera dans l’ordre suivant app.asar -> app -> default_app.asar. Lorsque ce fuse est activé, l’ordre de recherche devient une entrée unique app.asar garantissant ainsi que, lorsqu’il est combiné avec le fuse embeddedAsarIntegrityValidation , il est impossible de charger du code non validé.

loadBrowserProcessSpecificV8Snapshot

Par défaut: Désactivé

@electron/fuses: FuseV1Options.LoadBrowserProcessSpecificV8Snapshot

Le fuse loadBrowserProcessSpecificV8Snapshot modifie l'instantané utilisé pour le processus du navigateur. Par défaut, les processus d'Electron utiliseront tous le même fichier d'instantané V8. Lorsque ce fuse est activé, le processus du navigateur utilise le fichier browser_v8_context_snapshot.bin pour son instantané V8. Les autres processus utiliseront le fichier d'instantané V8 qu'ils utilisent normalement.

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

Par défaut: Activé

@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

Comment activer les fuses ?

La manière simple

Nous avons créé un module , @electron/fuses, facilitant le basculement de ceux-ci. Consultez le README de ce module pour plus de détails sur l'utilisation et les éventuels cas d'erreur.

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

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

Vous pouvez verifier que les fusibles ’une application Electron arbitraire ont été basculés ou bien vérifier leur état d à l’aide de la CLI des fuses.

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

La manière compliquée

Glossaire rapide

  • Fuse Wire: Une séquence d’octets dans le binaire d'Electron utilisé pour gérer les fuses
  • Sentinel: Une séquence statique d’octets connue que vous pouvez utiliser pour localiser le fuse wire
  • Fuse Schema: Le format et les valeurs autorisées pour le fuse wire

Pour activer les fuses manuellement, il est nécessaire d'éditer le binaire d'Electron et modifier la séquence d'octets du fuse wire pour qu'elle représente l'état des fuses désiré.

Quelque part dans le binaire Electron, il y a une séquence d'octets qui ressembler à ceci :

| ...binary | sentinel_bytes | fuse_version | fuse_wire_length | fuse_wire | ...binary |
  • sentinel_bytes est toujours exactement cette chaîne dL7pKGdnNz796PbbjQWNKmHXBZaB9tsX
  • fuse_version est un seul octet dont la valeur de type unsigned integer représente la version du schéma du fuse
  • fuse_wire_length est un seul octet dont la valeur de type unsigned integer représente le nombre de fuses dans le fuse wire
  • fuse_wire est une séquence de N octets, chaque octet représentant un seul fuse et son état.
    • "0" (0x30) indique que le fusible est inactif
    • "1" (0x31) indique que le fusible est actif
    • "r" (0x72) indique que le fuse a été supprimé et le changement de l'octet à 1 ou 0 n'aura aucun effet.

Pour actionner un fuse, vous devez trouver sa position dans le fuse wire et le mettre à "0" ou "1" selon l'état que vous désirez.

Vous pouvez voir le schéma actuel ici.