github electron-userland/electron-builder electron-updater@7.0.0-alpha.12

pre-release3 hours ago

Major Changes

  • Feat(win)!: a missing publisherName fails Windows update signature verification closed. #10380 674e18d — electron-updater, builder-util-runtime

    • electron-updater: an NSIS update is rejected with ERR_UPDATER_INVALID_SIGNATURE when app-update.yml (or dev-app-update.yml / the updateConfigPath file) has no publisherName. A custom verifyUpdateFileAuthenticodeSignature / verifyUpdateCodeSignature is never called without a publisherName. The only opt-out is verifyUpdateCodeSignature: false in app-update.yml, which electron-builder writes for win.verifyUpdateCodeSignature: false; verification is then skipped with one warning per updater. An app with no update config file at all (no app-update.yml / dev-app-update.yml, e.g. one that only uses setFeedURL) is not verified: its feed is configured by the developer.
    • app-builder-lib: a Windows build that writes app-update.yml (nsis, nsis-web or electronUpdaterAware appx with a publish configuration of any provider, including one inferred from a GitHub repository) fails with InvalidConfigurationError while win.verifyUpdateCodeSignature is enabled and no publisherName resolves: win.sign: false / null, no code signing certificate, or win.sign.publisherName: null, which is not an opt-out. Sign the build, set win.sign.publisherName (e.g. win.sign: { type: "signtool", publisherName: [...] } when signing outside electron-builder), or set win.verifyUpdateCodeSignature: false, which writes verifyUpdateCodeSignature: false (and no publisherName) into app-update.yml. A publisherName in the publish configuration must be a distinguished name too, and verifyUpdateCodeSignature must not be set there.
    • builder-util-runtime: PublishConfiguration has the private, Windows-only verifyUpdateCodeSignature field.
    • electron-builder: migrate-schema prints an advisory for win.sign: false / null or win.sign.publisherName: null without win.verifyUpdateCodeSignature: false.

    See https://www.electron.build/docs/migration/v27-build-changes#missing-publishername-fails-update-verification

  • Feat(win)!: matchPublisherName matches only publisher names that are a distinguished name (DN), every attribute of which must equal the signer's; a bare name never matches the signer's Common Name any more, and its logger parameter is removed. New export isValidPublisherNameDn tells whether a publisher name is a DN. See https://www.electron.build/docs/migration/v27-build-changes#windows-publishername-must-be-a-distinguished-name #10380 674e18d — builder-util-runtime

  • Feat(updater)!: Windows update signature verification fails closed — electron-updater installs an NSIS update only when PowerShell (Get-AuthenticodeSignature) verifies it: an update it cannot verify (PowerShell cannot be started or run, times out, or prints unreadable output) is rejected with ERR_UPDATER_SIGNATURE_UNVERIFIABLE, and a Windows catalog signature is rejected as invalid unless the app opts in with the new NsisUpdater.allowCatalogSignature (default false; when true, a valid catalog signature is accepted with a warning only when its signer matches publisherName). A release can allow it instead with the new win.allowCatalogSignature build option (default false), which writes allowCatalogSignature: true into the latest.yml of the nsis and nsis-web targets; electron-updater honors it only when that manifest's signature was verified against a trusted key (updateManifestPublicKey) and ignores it with a warning otherwise. The manifest signature covers it as an extra allowCatalogSignature:true line of the EBUM1 payload only when it is true, so manifests without it canonicalize and verify exactly as before, and changing it for a published release means re-signing or republishing latest.yml; a signed manifest with a non-boolean allowCatalogSignature is rejected. electron-updater 7.0.0-alpha.8 to alpha.11 installs with an update key configured reject a signed manifest that sets it (ERR_UPDATER_MANIFEST_SIGNATURE_INVALID), the same way alpha.8 treats a signed files[].blockMapUrl. UpdateInfoAndProvider gains manifestSignatureVerified, and BaseUpdater.verifyInstallerSignatureOnLaunch receives the update info the cached installer was matched against. PowerShell is started by absolute path, the installer path is passed in an environment variable, and non-ASCII output is escaped instead of setting a console encoding, so verification works under PowerShell Constrained Language Mode (fixing 7.0.0-alpha.8 to alpha.10). The build-time installer check uses the same invocation. builder-util-runtime adds prepareAuthenticodeSignatureExec and POWERSHELL_ASCII_ESCAPE_FUNCTION. Migration: where PowerShell may be blocked (AppLocker / WDAC), assign a native verifyUpdateFileAuthenticodeSignature in your first electron-updater 7 release — see https://www.electron.build/docs/migration/v27-runtime-changes#windows-update-signature-verification-fails-closed #10416 8366dc6 — electron-updater, builder-util-runtime

  • Feat(win)!: the default Authenticode verification of NSIS updates accepts an update only when a publisherName entry in distinguished name (DN) format (e.g. "CN=My Company, O=My Company, C=US") matches its signer: a bare name, which used to match the signer's Common Name with a warning, never matches. Such an entry (from an app-update.yml written by electron-builder before v27, a dev-app-update.yml or a direct call of verifyUpdateFileAuthenticodeSignature) is warned about once per updater, and the ERR_UPDATER_INVALID_SIGNATURE failure names it. Build the app with electron-builder v27, which writes a DN (CN=<common name> of the certificate unless publisherName is configured). See https://www.electron.build/docs/migration/v27-build-changes#windows-publishername-must-be-a-distinguished-name #10380 674e18d

  • Refactor(win)!: remove the escapePowerShellSingleQuotes export, which only shipped in 10.0.0-alpha.11; the Authenticode check passes the file path to PowerShell in an environment variable (prepareAuthenticodeSignatureExec), so no path is quoted into a PowerShell script. #10453 ed05bd0 — builder-util-runtime

Minor Changes

  • Feat: warn on silently skipped update signature verification and validate publisherName against the signing certificate at build time #10056 331afdd — updated in #10380

    Two guards around Windows update signature verification:

    • electron-updater: when app-update.yml exists but contains no publisherName, the updater used to skip signature verification (including custom verifyUpdateCodeSignature hooks) completely silently. It now logs a warning explaining that verification was skipped, how to fix it (sign the build so publisherName is derived automatically, or set win.publisherName explicitly), and that this fail-open behavior is deprecated. Since v27 (electron-updater 7), a missing publisherName in an existing app-update.yml is a verification failure (fail-closed) instead, unless the file has verifyUpdateCodeSignature: false. The no-app-update.yml path (unpackaged/dev mode) stays silent.
    • app-builder-lib: when publisherName is explicitly configured and the subject of the local code signing certificate is known, the build now fails with a clear error if none of the configured names match the certificate (same DN-subset/CN matching semantics as the updater's verifier; any one of multiple configured names matching passes, so certificate-rotation setups keep working). This catches signing with the wrong certificate at build time instead of at update time. The check is skipped whenever the actual signing certificate's subject is not genuinely known (custom sign hooks, Azure Trusted Signing, PKCS#11 without an extractable certificate, x509 files without a CN), and publisherName: null remains a pure opt-out.
  • Feat(runtime): HttpExecutor.addRedirectHandlers is public, so that requests made outside the executor (electron-updater's differential downloads) follow redirects with the same rules: credential headers are dropped on another origin, and the executor's redirect limit applies #10419 2d97c85 — builder-util-runtime

  • Feat(win): export windowsPowerShellPath(), which returns the absolute path of the in-box Windows PowerShell (%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe) for runtime use such as electron-updater, and throws when SystemRoot is not a drive-absolute path. preparePowerShellExec and prepareAuthenticodeSignatureExec take an optional PowerShell path, used instead of windowsPowerShellPath() when given. #10453 ed05bd0 — builder-util-runtime

Patch Changes

  • Fix(updater): differential downloads made with single range requests no longer send credential headers such as Authorization to a redirect target on another origin, which made pre-signed S3 or R2 URLs reject the range requests and forced a full download #10413 7167926
  • Refactor(win): export the Windows Authenticode helpers electron-updater verifies update signatures with (preparePowerShellExec, parseAuthenticodeSignatureOutput, matchPublisherName), moved from electron-updater so electron-builder can check signed installers with the same code #10378 60e3708 — builder-util-runtime · updated in #10416
  • Refactor(win): verify update signatures with the Authenticode helpers moved to builder-util-runtime #10378 60e3708 — updated in #10416
  • Docs: split the v27 breaking-changes page into config, build, runtime and developer pages, point the migration links in build and updater messages at the page each change moved to, and add links to the v27 messages that had none #10421 b5e144d
  • Start system tools by absolute path instead of looking them up on PATH: Windows PowerShell from %SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe (for Windows code signing, package-manager commands and create-self-signed-cert), PowerShell 7 from %ProgramFiles%\PowerShell\7\pwsh.exe on Windows and from the install location of Microsoft's package on macOS and Linux, prlctl from the Parallels Desktop install location, and the host Wine (toolsets.wine: "system", the default) from its fixed install locations. SystemRoot and ProgramFiles must be drive-absolute paths. #10422 a7f005c — builder-util-runtime
  • Electron-builder starts the host programs it uses only from an absolute path, never by looking up a name on PATH: PowerShell, Wine, Mono (Squirrel.Windows on macOS and Linux), prlctl, productbuild, pkgbuild, codesign, hdiutil, tiffutil, sips, actool, zip, notarytool (passed to @electron/notarize as notarytoolPath, located with /usr/bin/xcrun by default), lzip, snapcraft, flatpak and flatpak-builder. Each comes from its default install locations or from the new toolsets.executables map, whose entries are file:// URIs, or lists of them, that replace the defaults for that program. Child processes started without an explicit environment get no credential variables on Windows either, and snapcraft upload gets the store credentials but no other secret. The NSIS installer starts tasklist and taskkill from $SYSDIR (and passes the force flag in per-machine mode), the AppImage launcher runs the dialog tool it checked by its absolute path, and electron-updater on macOS starts /usr/sbin/sysctl and /usr/bin/uname. #10430 b98e1f2
  • Fix(updater): every request of a differential download (single-range, multi-range and reading the embedded block map) follows redirects through ElectronHttpExecutor.addRedirectHandlers: credential headers such as Authorization, PRIVATE-TOKEN, X-Api-Key and Cookie are sent to a redirect target only on the same origin, a single-range download requests its remaining ranges from the redirect target while each multi-range request starts at the update URL, and at most 10 redirects are followed per request, as for every ElectronHttpExecutor request #10419 2d97c85
  • Fix(runtime): HttpExecutor.prepareRedirectUrlOptions leaves out host, so a redirected request goes to the redirect target even when the original request set host (ElectronHttpExecutor sets it from a Host header) #10419 2d97c85 — builder-util-runtime
  • Fix: escaped characters in a Windows publisherName distinguished name are decoded correctly. Before, a hex pair was decoded as a single Latin-1 character (Caf\C3\A9 became Café instead of Café), and a \+ or \ escape followed by a hex digit was read as a hex pair (Acme\+Bolt lost the B), so such a publisher name never matched the signing certificate and electron-updater rejected the update #10434 6393d7a — builder-util-runtime
  • Fix(updater): settle a cancelled differential download with a CancellationError instead of hanging or falling back to a full download, and log a throwing download-progress listener instead of letting it break the download or keep progress from the other listeners #10356 7efb3e6
  • Fix: secrets in logs and error messages (passwords, tokens and keys in redacted command lines, environments and request options) are shown as a fingerprint keyed with a random secret of the process, derived with scrypt: the same value has the same fingerprint within a run, but a fingerprint cannot be checked against guessed values offline. A value whose fingerprint cannot be computed is shown as <redacted>. #10441 955cd00 — electron-updater, builder-util-runtime
  • Fix: Fall back to Latin-1 when a hex escape in a distinguished name is not valid UTF-8 #10446 5028cb3 — builder-util-runtime
  • Fix: reject update download redirects to non-HTTP(S) URLs instead of throwing an uncaught exception #10448 f68074d
  • Fix(updater): the ERR_UPDATER_INVALID_SIGNATURE error for an app-update.yml without publisherName says how to configure one (sign the build or set win.sign.publisherName) and that win.verifyUpdateCodeSignature: false is the opt-out, with a link to the migration guide. #10453 ed05bd0

Don't miss a new electron-builder release

NewReleases is sending notifications on new releases.