Skip to content

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

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

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

Conversation

@mmaietta

@mmaietta mmaietta commented May 22, 2026

Copy link
Copy Markdown
Collaborator

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

changeset-bot Bot commented May 22, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 2e4e003

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

Copilot AI left a comment

Copy link
Copy Markdown

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

Copilot AI left a comment

Copy link
Copy Markdown

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.

Copilot AI left a comment

Copy link
Copy Markdown

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
@mayfield

mayfield commented Jul 8, 2026

Copy link
Copy Markdown

Is this going to get merged? I have users reporting errors upgrading and I'm hoping this fixes it.

@mmaietta

mmaietta commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator Author

I do plan to revisit this PR, but I had to pause work due to personal events. Hoping to reapply focus here soon. There was additional testing I was looking to do.

claude added 2 commits July 11, 2026 06:28
Resolves conflict in windowsExecutableCodeSignatureVerifier.ts:
master's inline verifySignature body (removed by this PR's helper
extraction) conflicted with the restructured version. Kept the PR's
helper-based structure and ported master's new fail-open deprecation
warning (#9979) into checkLiteralPath's catch block. The other two
deprecation warnings in handleError and the ESM types.js import
auto-merged cleanly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Cb9bMJZft1o1hHc9P6jp2W
…slint curly rule)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Cb9bMJZft1o1hHc9P6jp2W
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

4 participants