8000 Security: auto-updater installs unsigned artifacts with no authenticity verification (quarantine window is the only defense) · Issue #71 · amirlehmam/wmux · GitHub
[go: up one dir, main page]

Skip to content
< 8000 link rel="preload" as="image" href="https://github.githubassets.com/assets/platform-dark-ac89fbf373737ed3.png"/>

Security: auto-updater installs unsigned artifacts with no authenticity verification (quarantine window is the only defense) #71

Closed

Description

@Rajveerx11

Summary

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 no certificateFile / 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)

  1. 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).
  2. Add the signing config to electron-builder.json (win.certificateSubjectName / SignPath publisher) so electron-updater verifies the publisher on install.
  3. 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.
  4. 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.

Activity

  1. added a commit that references this issue on Jul 7, 2026
    2e2b37d
  2. amirlehmam commented on Jul 7, 2026

    @amirlehmam
    Owner

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0