Repository navigation
Conversation
Shipped v7.9.0 binaries are on fuse wire version 1, meaning @electron/fuses has never run against the build. RunAsNode, EnableNodeOptionsEnvironmentVariable and EnableNodeCliInspectArguments are all left at their permissive framework defaults. With RunAsNode enabled, ELECTRON_RUN_AS_NODE=1 <app> starts the binary as a plain Node runtime, dropping the Electron sandbox entirely. EnableNodeOptionsEnvironmentVariable means NODE_OPTIONS is honoured, so a controlled launch environment can inject --require and load code at startup. EnableNodeCliInspectArguments lets a launch argument attach the Node inspector to the renderer process. None of these are remotely exploitable and none need an embargo. They are the Electron framework defaults, so this is not a bug introduced here. It is the set of switches that were never closed. Adds fuse flipping to the existing afterPack hook so it applies to all three packaged platforms (win/mac/linux). Two deliberate omissions: - EnableEmbeddedAsarIntegrityValidation is left off. It requires the matching `asarIntegrity` option in electron-builder.js, and enabling the fuse without that prevents the app from launching. Worth a separate change. - GrantFileProtocolExtraPrivileges is left at its default, since turning it off breaks file:// handling. OnlyLoadAppFromAsar is set, which is the protection that actually matters here. This runs in afterPack rather than postinstall, so @electron/fuses stays a devDependency and there is no Electron rebuild notice on every npm install.
`pnpm install --frozen-lockfile` failed because pnpm-lock.yaml did not know about the new devDependency, which would have broken CI. Also applies the formatting oxfmt wants for scripts/afterPack.js. Verified locally with the project's own tooling: $ pnpm check pass: All 491 files are correctly formatted pass: Found no warnings or lint errors in 440 files
|
Pushing an update while this is under review, since I found a problem I should have caught before opening. I had added So CI would have failed on the first run. What I have now verified locally, rather than assumed: The pre-commit hook also runs On the format change specifically: Two caveats I want to be explicit about, since neither is covered by the checks above:
|
What
Adds Electron fuse flipping to the existing
scripts/afterPack.js, so packaged builds ship with the hardening switches closed rather than at their framework defaults.Why
I unpacked the shipped v7.9.0 Windows build and read the fuse wire out of
Gitify.exe. It reports fuse wire version 1, which means@electron/fuseshas never been run against the build, so every switch is sitting at its Electron default rather than a deliberate choice:run_as_nodeenable_node_options_envenable_node_cli_inspect_argsTo be clear about what this is and is not: none of these are remotely exploitable, and none of them are a bug introduced by Gitify. They are the Electron framework defaults. The point is that the three which matter were never closed.
Concretely, on a machine where something can influence how the app is launched:
ELECTRON_RUN_AS_NODE=1 Gitify.exeruns the binary as a plain Node runtime, dropping the Electron sandbox.NODE_OPTIONSis honoured, so a controlled launch environment can inject--requireand load code at startup.How I verified the fix
I applied this exact configuration to a copy of the shipped
Gitify.exeand re-read the wire with both@electron/fusesand an independent decoder:As raw bytes, the patch touches 5 bytes of a 245,726,208-byte binary, all inside the 9-entry wire, and the file length is unchanged:
Two deliberate omissions
EnableEmbeddedAsarIntegrityValidationis left off. It requires a matchingasarIntegrityoption inelectron-builder.js, which is not currently set, and enabling the fuse without that prevents the app from launching. I think it is worth enabling, but it belongs in its own change where the build config moves with it.GrantFileProtocolExtraPrivilegesis left at its default, because turning it off breaksfile://handling.OnlyLoadAppFromAsaris set, which is the protection that actually matters for this change.Why
afterPackand notpostinstallKeeps
@electron/fusesindevDependenciesand avoids an "Electron was rebuilt" notice on everynpm install.afterPackalso already exists in the repo, so this is one hook covering win/mac/linux rather than three platform scripts.Note on the API, in case it catches anyone else
@electron/fusesv2 changed shape from v1.x:FuseV2Optionsno longer exists (all names moved underFuseV1Options), andflipFusesnow takes(executablePath, config)rather than(config, executablePath). Both are commented in the file.Testing
node --checkpasses, and I confirmed the executable-path resolution returns the right location for each platform (darwin->Contents/MacOS/<app>,win32-><app>.exe, default -><app>). The hook also no-ops with a log line if the executable is not found, so a packaging change cannot silently skip the flip.I have not run a full
pnpm package:winbuild, so the three platform paths are verified by inspection rather than by producing all three artifacts.Happy to split any part of this out, or to drop it entirely if the timing is not right.