Security: auto-updater installs unsigned artifacts with no authenticity verification (quarantine window is the only defense) · Issue #71 · amirlehmam/wmux · GitHub
You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Security: auto-updater installs unsigned artifacts with no authenticity verification (quarantine window is the only defense) #71
wmux ships unsigned release artifacts and the auto-updater performs no cryptographic authenticity check on what it downloads. The recently added 3‑day quarantine window (src/main/updater.ts) is currently the only defense against a malicious release — it buys detection time, but it does not verify who built the artifact. updater.ts itself flags this as an unshipped follow‑up:
// (Signature verification + Authenticode + build provenance are tracked as
// follow-ups in the issue; they need offline keys / CI changes, not just code.)
Where it stands in the code
electron-builder.json — the win target has an icon but nocertificateFile / certificateSubjectName / CSC config, so the produced .exe/NSIS/portable binaries are unsigned.
.github/workflows/release.yml:58 — the SignPath Authenticode signing steps are entirely commented out (# ── Sign exe with SignPath (disabled — waiting for OSS approval) ──).
src/main/updater.ts — uses electron-updater with autoDownload=false + quarantine gating, but nothing calls into publisher-signature verification. On Windows, electron-updater can only verify a publisher signature when the build is actually Authenticode-signed; with unsigned builds that check is a no‑op.
Why it matters
electron-updater's only integrity check on an unsigned Windows build is the SHA512 in latest.yml — but latest.yml is served from the same GitHub release as the installer, so it is self‑referential, not an authenticity guarantee. Anyone able to publish/replace a release (leaked maintainer token, compromised CI, or a future malicious-owner scenario) can ship a matching latest.yml + trojaned installer, and every client silently downloads it once the quarantine window elapses. That is effectively RCE-on-update for the whole install base, gated only by a 3‑day timer.
Proposed fix (contributable, mostly config/CI)
Re-enable Authenticode signing in release.yml (uncomment/finish the SignPath OSS flow, or wire a self-managed cert via CSC_LINK/CSC_KEY_PASSWORD).
Add the signing config to electron-builder.json (win.certificateSubjectName / SignPath publisher) so electron-updater verifies the publisher on install.
Optionally pin an allowed publisher name and reject updates whose signature doesn't match, so the quarantine window becomes defense-in-depth rather than the sole control.
Document WMUX_DISABLE_UPDATER=1 as the interim mitigation for security-sensitive users until signing lands.
Happy to open a PR wiring up the electron-builder signing config + the release.yml steps behind the existing SignPath secrets.
The signing pipeline from #74 is merged and shipped in v0.17.0 — thanks @Rajveerx11.
Status, honestly:
✅ The SignPath steps are live in release.yml (correctly ordered after rcedit, with a hard Get-AuthenticodeSignature verification before shipping a signed artifact), and the SIGNPATH_* secrets are configured on the repo.
✅ electron-updater publisher verification is pinned to SignPath Foundation (moved to win.signtoolOptions.publisherName — electron-builder 26 relocated that key).
✅ README now documents the quarantine window and WMUX_DISABLE_UPDATER=1 / WMUX_MIN_RELEASE_AGE_DAYS for security-sensitive environments.
⚠️v0.17.0 itself is still unsigned: the first live signing run came back 400 — Yearly quota for artifact size has been exceeded from SignPath OSS. The workflow now treats a rejected submission as non-fatal (ships unsigned with a warning, exactly the pre-existing posture) while keeping verification of a downloaded signed artifact fatal. Signing will kick in automatically on the first release after quota is available — no further code changes needed.
Until then, the 3-day update quarantine + explicit install confirmation remain the client-side controls, and the zip-artifact limitation you flagged in the PR is the acknowledged follow-up.
Activity
ci: wire SignPath Authenticode signing behind secrets + pin publisher (…
Merge pull request #74 from Rajveerx11/fix/71-updater-signing
amirlehmam commentedon Jul 7, 2026
The signing pipeline from #74 is merged and shipped in v0.17.0 — thanks @Rajveerx11.
Status, honestly:
release.yml(correctly ordered after rcedit, with a hardGet-AuthenticodeSignatureverification before shipping a signed artifact), and theSIGNPATH_*secrets are configured on the repo.electron-updaterpublisher verification is pinned toSignPath Foundation(moved towin.signtoolOptions.publisherName— electron-builder 26 relocated that key).WMUX_DISABLE_UPDATER=1/WMUX_MIN_RELEASE_AGE_DAYSfor security-sensitive environments.400 — Yearly quota for artifact size has been exceededfrom SignPath OSS. The workflow now treats a rejected submission as non-fatal (ships unsigned with a warning, exactly the pre-existing posture) while keeping verification of a downloaded signed artifact fatal. Signing will kick in automatically on the first release after quota is available — no further code changes needed.Until then, the 3-day update quarantine + explicit install confirmation remain the client-side controls, and the zip-artifact limitation you flagged in the PR is the acknowledged follow-up.
fix(updater): ship signed NSIS installer so Windows auto-update installs