Skip to content

Commit

Permalink
docs: add fuses and asar integrity docs (#35595)
Browse files Browse the repository at this point in the history
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
  • Loading branch information
trop[bot] and MarshallOfSound committed Sep 7, 2022
1 parent 61f385a commit c730abc
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 1 deletion.
53 changes: 53 additions & 0 deletions docs/tutorial/asar-integrity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
title: 'ASAR Integrity'
description: 'An experimental feature that ensures the validity of ASAR contents at runtime.'
slug: asar-integrity
hide_title: false
---

## Platform Support

Currently ASAR integrity checking is only supported on macOS.

## Requirements

### Electron Forge / Electron Packager

If you are using `>= electron-packager@15.4.0` or `>= @electron-forge/core@6.0.0-beta.61` then all these requirements are met for you automatically and you can skip to [Toggling the Fuse](#toggling-the-fuse).

### Other build systems

In order to enable ASAR integrity checking you need to ensure that your `app.asar` file was generated by a version of the `asar` npm package that supports asar integrity. Support was introduced in version `3.1.0`.

Your must then populate a valid `ElectronAsarIntegrity` dictionary block in your packaged apps `Info.plist`. An example is included below.

```plist
<key>ElectronAsarIntegrity</key>
<dict>
<key>Resources/app.asar</key>
<dict>
<key>algorithm</key>
<string>SHA256</string>
<key>hash</key>
<string>9d1f61ea03c4bb62b4416387a521101b81151da0cfbe18c9f8c8b818c5cebfac</string>
</dict>
</dict>
```

Valid `algorithm` values are currently `SHA256` only. The `hash` is a hash of the ASAR header using the given algorithm. The `asar` package exposes a `getRawHeader` method whose result can then be hashed to generate this value.

## Toggling the Fuse

ASAR integrity checking is currently disabled by default and can be enabled by toggling a fuse. See [Electron Fuses](fuses.md) for more information on what Electron Fuses are and how they work. When enabling this fuse you typically also want to enable the `onlyLoadAppFromAsar` fuse otherwise the validity checking can be bypassed via the Electron app code search path.

```js
require('@electron/fuses').flipFuses(
// E.g. /a/b/Foo.app
pathToPackagedApp,
{
version: FuseVersion.V1,
[FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
[FuseV1Options.OnlyLoadAppFromAsar]: true
}
)
```
55 changes: 54 additions & 1 deletion docs/tutorial/fuses.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,52 @@ For a subset of Electron functionality it makes sense to disable certain feature

Fuses are the solution to this problem, at a high level they are "magic bits" in the Electron binary that can be flipped when packaging your Electron app to enable / disable certain features / restrictions. Because they are flipped at package time before you code sign your app the OS becomes responsible for ensuring those bits aren't flipped back via OS level code signing validation (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.

### `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. Most apps can safely enable this fuse.

### `nodeOptions`

**Default:** Enabled
**@electron/fuses:** `FuseV1Options.EnableNodeOptionsEnvironmentVariable`

The nodeOptions fuse toggles whether the [`NODE_OPTIONS`](https://nodejs.org/api/cli.html#node_optionsoptions) environment variable is respected or not. This 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. Most apps can safely disable this fuse.

### `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. Most apps can safely disable this fuse.

### `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](asar-integrity.md) documentation.

### `onlyLoadAppFromAsar`

**Default:** Disabled
**@electron/fuses:** `FuseV1Options.OnlyLoadAppFromAsar`

The onlyLoadAppFromAsar fuse changes the search system that Electron uses to locate your app code. By default Electron will search in the following order `app.asar` -> `app` -> `default_app.asasr`. 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.

## How do I flip the fuses?

### The easy way
Expand All @@ -20,11 +66,18 @@ require('@electron/fuses').flipFuses(
require('electron'),
// Fuses to flip
{
runAsNode: false
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.

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

### The hard way

#### Quick Glossary
Expand Down

0 comments on commit c730abc

Please sign in to comment.