Skip to content

feat(updater): robust PowerShell invocation for Windows code-signature verification#9764

Open
mmaietta wants to merge 11 commits into
masterfrom
window-sign-verifier
Open

feat(updater): robust PowerShell invocation for Windows code-signature verification#9764
mmaietta wants to merge 11 commits into
masterfrom
window-sign-verifier

Conversation

@mmaietta
Copy link
Copy Markdown
Collaborator

@mmaietta mmaietta commented May 22, 2026

Fixes #9688Get-AuthenticodeSignature failures on Windows 10 / Electron 40 / Node 24 configurations.

Summary

  • Core fix — shell: false + -EncodedCommand: PowerShell is now invoked directly via execFile instead of being chained through cmd.exe. The command is passed as a Base64-encoded UTF-16LE string via -EncodedCommand, removing the cmd.exe invocation and the chcp 65001 >NUL & pipeline entirely.

  • UTF-8 output encoding: Moved from the chcp 65001 shell command to $OutputEncoding = [Console]::OutputEncoding = [Text.Encoding]::UTF8 configured inside the PowerShell script. Both variables must be set together for ConvertTo-Json to emit UTF-8 when stdout is captured by Node (fixes Certificates with special characters are not accepted anymore since electron-updater v1.6.9 #8162 class of errors — non-ASCII characters in the update path).

  • Module loading hardened: Import-Module uses "$PSHOME\Modules\Microsoft.PowerShell.Security" (PowerShell's own trusted install directory) before $env:PSModulePath is cleared, so the correct module is loaded even on Windows Server 2025 where auto-loading requires PSModulePath at import time. PSModulePath is also deleted from the Node-side env option as belt-and-suspenders.

  • Progress-stream suppression: $ProgressPreference = 'SilentlyContinue' is set first in the script so the "Preparing modules for first use." CLIXML record is never written to stderr, eliminating false-positive error detection on first-run environments.

  • Bug fix — double-reject in handleError: The previous if (error) { reject() } if (stderr) { reject() } pattern could settle the Promise twice when both fields were set. Corrected to else if.

  • Typo fix: normlaizedUpdateFilePathnormalizedUpdateFilePath.

  • Reduced cyclomatic complexity: Extracted three private helpers to flatten verifySignature (CC 6 → 3):

    • checkLiteralPath — validates data.Path against the expected update path and calls reject() directly on mismatch (removes the spurious ConvertTo-Json probe on path-mismatch failures).
    • matchPublisher — DN matching loop.
    • evaluateSignatureResult — parses the PS JSON output and coordinates the LiteralPath + publisher checks.
  • Path injection comment trimmed: Multi-line example block replaced with a 2-line explanation (WHY only — PowerShell single-quoted strings make $, `, and \ literal; only ' needs escaping).

  • Test — vi.importActual moved to beforeAll: In the e2e describe block, the expensive vi.importActual calls for real child_process and os implementations are obtained once in beforeAll rather than re-fetched before every test in beforeEach.

  • Test coverage (unit, platform-agnostic): 46 tests pass, up from 41. New cases cover:

    • Status 3 (HashMismatch) and Status 4 (NotSupportedFileFormat) return non-null error strings.
    • Empty stdout ("") rejects via the catch path (JSON.parse throws).
    • $ in path is passed verbatim inside the single-quoted PS string.
    • Backtick in path is passed verbatim inside the single-quoted PS string.
  • Test coverage (e2e, Windows-only describe.ifWindows): 4 new real-PowerShell tests validate that directory names containing &, %VAR%, $, and backtick characters — which were dangerous under the old cmd.exe-based invocation — now complete without crash or spurious rejection.

Changed Files

File Change
packages/electron-updater/src/windowsExecutableCodeSignatureVerifier.ts Core fix: shell: false, -EncodedCommand, helper extraction, bug fixes, comment cleanup
test/src/updater/windowsExecutableCodeSignatureVerifierTest.ts +5 unit tests, +4 e2e tests; vi.importActual moved to beforeAll
test/snapshots/updater/windowsExecutableCodeSignatureVerifierTest.js.snap Snapshot of encoded script (path placeholder replaces dynamic tmp path)

…Encoding = [Console]::OutputEncoding = [Text.Encoding]::UTF8` for windows signing verification via powershell
@mmaietta mmaietta requested a review from Copilot May 22, 2026 02:11
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 22, 2026

🦋 Changeset detected

Latest commit: fc65654

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
electron-updater Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates how electron-updater invokes PowerShell to verify Windows Authenticode signatures, aiming to improve reliability on newer Windows Server versions and to ensure UTF-8 output handling without going through cmd.exe.

Changes:

  • Refactor PowerShell invocation to use shell: false + -EncodedCommand, and configure UTF-8 output inside PowerShell.
  • Adjust module-loading / PSModulePath handling intended to avoid autoload issues on newer Windows Server versions.
  • Add unit + Windows-only e2e tests (with a snapshot) covering invocation parameters, escaping, and key verification behaviors.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
packages/electron-updater/src/windowsExecutableCodeSignatureVerifier.ts Refactors preparePowerShellExec to use -EncodedCommand, sets shell: false, and moves encoding/module setup into the PowerShell script.
test/src/updater/windowsExecutableCodeSignatureVerifierTest.ts Adds comprehensive unit tests (mocked) and Windows-only e2e tests (real PowerShell) for signature verification and command construction/escaping.
test/snapshots/updater/windowsExecutableCodeSignatureVerifierTest.js.snap Adds snapshot for the PowerShell executable + args (including encoded command).
.changeset/late-results-grab.md Declares a minor changeset for electron-updater reflecting the PowerShell invocation change.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/electron-updater/src/windowsExecutableCodeSignatureVerifier.ts Outdated
Comment thread test/src/updater/windowsExecutableCodeSignatureVerifierTest.ts Outdated
Comment thread test/src/updater/windowsExecutableCodeSignatureVerifierTest.ts
Comment thread test/src/updater/windowsExecutableCodeSignatureVerifierTest.ts
Comment thread test/src/updater/windowsExecutableCodeSignatureVerifierTest.ts Outdated
@mmaietta mmaietta changed the title feat(updater): use shell: false and -EncodedCommand for windows signing verification via powershell feat(updater): robust PowerShell invocation for Windows code-signature verification May 31, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

Comment thread packages/electron-updater/src/windowsExecutableCodeSignatureVerifier.ts Outdated
Comment thread packages/electron-updater/src/windowsExecutableCodeSignatureVerifier.ts Outdated
@mmaietta mmaietta marked this pull request as ready for review June 1, 2026 18:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Powershell Get-AuthenticodeSignature fails Certificates with special characters are not accepted anymore since electron-updater v1.6.9

2 participants