An auto-updater is a remote code execution channel that you built on purpose, and anyone who controls it controls every installed copy of your application. Desktop applications that fetch updates over plain HTTP, accept unsigned packages, or trust a single online signing key turn one server or key compromise into a mass compromise of customer endpoints. This guide explains the threats to update systems as The Update Framework (TUF) specification defines them, how mainstream desktop updaters such as Sparkle, Squirrel and MSIX verify updates, how to design signing and key management, how to roll out changes safely and how to monitor the update channel. It is written for desktop application developers, release engineers and product security teams, and for enterprise security teams assessing the updaters of software they deploy. For browser-specific update and hardening settings, see the Browser Security Hardening Guide.
Key takeaways
- Transport security is not update security. HTTPS protects the download path, but only a signature verified by the client against a key it already trusts proves the update came from you.
- Verify before you execute. The updater must check the signature and the expected hash and size before unpacking or running anything, and reject on any failure.
- Plan for key compromise. TUF's design goal is that compromising a single key, or fewer than a threshold of keys, cannot compromise clients. Separate offline root keys from online keys and support rotation.
- Prevent rollback and freeze. Clients should refuse versions older than ones they have already seen and notice when metadata stops changing.
- The build is part of the update channel. A signed update built from a tampered pipeline is still malicious, as the SolarWinds Orion compromise showed.
The threat model for software updates
The TUF specification (version 1.0.37, dated 8 October 2026 in the specification repository) lists the attacks a secure update system must resist. They are a useful checklist for any updater, whether or not you adopt TUF itself:
| Attack (TUF name) | What the attacker achieves | Defensive design |
|---|---|---|
| Arbitrary installation | Serves any file in response to a download request | Client-side signature verification against pinned keys |
| Rollback | Installs an older, vulnerable version the client previously knew was superseded | Monotonic version check stored on the client |
| Indefinite freeze | Keeps serving the same outdated metadata so the client never learns of fixes | Signed metadata with expiry; alert when expired |
| Fast-forward | Inflates version numbers so genuine updates look like rollbacks | Signed snapshot metadata and recovery procedures |
| Mix-and-match | Combines metadata files that never existed together | Snapshot metadata covering all targets metadata |
| Endless data | Sends huge responses to exhaust disk or memory | Expected size in signed metadata; download limits |
| Extraneous dependencies | Causes unintended dependencies to be installed | Signed list of exactly what to install |
| Wrong software installation | Delivers a trusted file that is not the one requested | Hash of each target in signed metadata |
| Malicious mirrors | Prevents updates from good mirrors | Multiple mirrors with signed metadata |
| Key compromise | Uses one stolen key to sign malicious updates | Role separation, thresholds, offline root keys |
TUF notes that an attacker who can intercept traffic can always cause denial of service, so the framework must at least detect when a client cannot update. In MITRE ATT&CK terms, the update channel is exposed to T1195.002 Compromise Software Supply Chain and, where transport is weak, T1557 Adversary-in-the-Middle; stolen or misused signing material relates to T1588.003 Code Signing Certificates and T1553.002 Code Signing.
How TUF structures trust
TUF separates responsibilities into roles, each with its own keys and a threshold of signatures required:
- Root: delegates trust to the keys for all other roles. The client must ship with trusted root keys, and the specification says root private keys should be kept offline. If a threshold of root keys is compromised, the specification says it is safest to assume attackers have taken over affected machines, which is why root keys warrant the strongest protection.
- Targets: signs metadata describing the files (hashes and sizes), not the files themselves, and can delegate full or partial trust to other roles, for example per product or per team.
- Snapshot: signs the latest versions of all targets metadata, preventing mix-and-match attacks.
- Timestamp: an automated, online key that periodically signs a statement with the hash of the snapshot, defeating replay of stale metadata. The specification says the risk from compromise of this online key is minimal.
- Mirrors: optional signed mirror lists.
Implementations exist for several languages (python-tuf, go-tuf, tuf-js and others listed on the project site). If you run your own update service, TUF or a design that meets the same goals is the most robust option. If you rely on a platform updater, map its protections against the table above and close the gaps. The same principles underpin firmware updates; see the IoT Secure Firmware Update Guide (SUIT, signed OTA).
Platform updaters compared
| Updater | Integrity mechanism (per project documentation) | Gaps to close |
|---|---|---|
| Sparkle 2 (macOS) | Updates verified with EdDSA (ed25519) signatures and Apple code signing; public key in SUPublicEDKey in Info.plist; private key stored in the login Keychain by generate_keys; HTTPS and App Transport Security recommended | Keep the EdDSA private key off build servers and web hosts; plan rotation (Sparkle allows changing either the code signing certificate or the EdDSA key in one update, not both) |
Squirrel.Mac via Electron autoUpdater | The app must be code signed for automatic updates on macOS; App Transport Security applies to update requests; update entries may declare sha256 and size, and mismatching downloads are discarded before unpacking; delta patches go through the same code signing verification | Do not disable ATS with NSAllowsArbitraryLoads; publish hashes in the feed |
Squirrel.Windows via Electron autoUpdater | Reads a RELEASES file listing package hashes, names and sizes from the update server | Sign the installer and binaries with Authenticode; serve the feed only over HTTPS; protect the feed host as a release system |
| MSIX (Windows) | Electron's autoUpdater uses the MSIX updater for apps running as MSIX packages; MSIX packages must be signed to install | Manage the package signing certificate as a high-value key |
| Custom updater | Whatever you build | Usually the weakest option; adopt TUF or a reviewed framework rather than writing verification yourself |
For Electron-specific hardening beyond updates, see the Electron and Desktop App Security Guide.
Signing keys and where identity fits
Update signing keys are among the most valuable non-human credentials an organisation holds: whoever holds them can push code to every customer. Treat them as privileged machine identities:
- Separate keys by purpose: platform code signing (Authenticode, Apple Developer ID), update metadata signing (EdDSA or TUF roles) and TLS for the update host should be different keys with different owners.
- Keep root keys offline: generate them on an air-gapped machine or HSM, require multiple custodians, and use them only to rotate other keys.
- Protect online keys: store CI signing keys in an HSM or cloud KMS, allow signing only from the protected release pipeline identity, and log every signing operation.
- Keep keys away from the distribution host: Sparkle's documentation advises keeping signing keys off the machine hosting the product so a web server compromise does not expose them.
- Plan rotation and revocation: ship the next key's public half before you need it, and rehearse an emergency rotation.
- Least privilege for release identities: CI service accounts that publish to the update host should have write access only to their own release paths.
See the Code Signing Security Guide and the Compromised Code Signing Certificate Playbook.
Implementing a secure update pipeline
- Inventory update paths. List every way the application updates itself, including plug-in, extension, model or content downloads that execute code. Each is an update channel.
- Enforce HTTPS everywhere. Feed, metadata and package URLs must use HTTPS with certificate validation; never allow fallback to HTTP.
- Add client-side signature verification. Pin the update verification public key in the shipped application, verify signature, hash and size before extraction, and fail closed.
- Add rollback and freeze protection. Store the highest version installed and refuse lower versions; add expiry to signed metadata and surface "unable to update" to the user and telemetry.
- Harden the build. Build releases only in CI from reviewed source, produce provenance, and sign as the last step in an isolated job. Compare the built artefact hash with a second independent build where reproducible builds are feasible.
- Stage rollouts. Release to an internal ring, then a small percentage of users, then everyone, with an automated halt on crash or error spikes.
- Prepare rollback. Rolling back must be a new, higher-versioned release containing the old code, so rollback protection is not weakened. Keep a signed "known good" build ready.
- Test the failure paths. In a test environment, serve a tampered package, a wrong signature, an old version and expired metadata, and confirm the client rejects each. Add these as automated tests.
Decision guidance
- Small vendor, one platform: use the platform's maintained updater (Sparkle on macOS, MSIX or a maintained Squirrel-based updater on Windows), sign with the platform mechanism plus the updater's own signature, and keep the private key in a hardware token.
- Vendor with many products or third-party publishers: TUF's delegations let each product or team sign its own targets while root stays central and offline.
- Enterprise customers: many organisations disable in-app updaters and deploy through their own software distribution tools. Offer a documented way to disable auto-update by policy and publish signed packages for enterprise deployment, but remember the enterprise distribution tool then becomes the update channel, exposed to T1072 Software Deployment Tools.
- Security-critical software (agents, VPN clients, endpoint tools): require threshold signing for releases and staged rollout. The Third-Party Concentration Risk Guide (lessons from the July 2024 CrowdStrike Outage) shows why update speed must be balanced with staged deployment even when nothing is malicious.
Assessing a vendor's updater
Enterprise security teams rarely get to choose the updater inside third-party software, but they can assess it and decide how to deploy. Questions to ask software vendors, and checks you can run yourself in a lab:
- Transport: does the application ever fetch update metadata or packages over HTTP? Proxy the traffic in a lab and look for clear-text requests or ignored certificate errors.
- Verification: what is verified on the client (platform signature, updater signature, hash and size), against which key, and is it checked before extraction?
- Key custody: where are update signing keys held (HSM, cloud KMS, hardware token), who can use them, and are root keys offline?
- Rollback protection: will the client install an older signed version if offered one?
- Build integrity: are releases built in CI with provenance, and does the vendor publish SBOMs or attestations for releases?
- Staged rollout and pause: does the vendor stage releases, and can customers delay or pin versions by policy?
- Enterprise controls: can auto-update be disabled or redirected to an internal mirror through group policy, MDM profile or configuration file?
- Incident history: has the vendor disclosed any update channel or signing key compromise, and how was it handled?
Record the answers in your third-party risk assessment and decide per application whether to allow in-app updates, route them through an internal mirror, or deploy only through your own distribution tooling. Applications that run with administrative rights, such as endpoint agents and VPN clients, deserve the strictest review because their updater runs with the same privileges. Where an updater runs as a privileged service, check that the service validates the package signer itself rather than trusting a path that a standard user can write to.
Detection and measurement
Vendors should monitor:
- Every signing operation (who, what artefact hash, which pipeline run), alerting on signatures outside the release pipeline.
- Changes to update feeds, metadata and files on the distribution host, compared against the release record.
- Client telemetry for verification failures, rollback rejections and expired metadata, which can indicate tampering or AiTM attempts.
Enterprise security teams should watch for updater processes spawning unexpected child processes, update binaries with invalid or unexpected signers, and updater traffic to unexpected hosts. See the SocGholish and Fake Browser Update Malware Guide for the related social engineering pattern of fake updates.
| Metric | Target |
|---|---|
| Update channels using HTTPS and client-side signature verification | 100% |
| Signing operations traceable to a release pipeline run | 100% |
| Releases shipped through staged rollout rings | 100% for security-critical products |
| Time to rotate an update signing key in a rehearsal | Measured and falling |
| Client verification failure rate | Baseline established; spikes investigated |
Common failure patterns
- HTTP feeds or packages: any unauthenticated hop lets an on-path attacker substitute the update.
- Verifying after extraction or execution: archive parsing and installer scripts run before the check, so a malicious package can act before it is rejected.
- Signing keys on the build or web server: one compromise yields both the ability to sign and to distribute.
- Trusting the pipeline blindly: in the SolarWinds supply chain compromise, attackers inserted the SUNBURST backdoor into Orion builds without changing the source repository, and the tampered builds were signed and shipped as normal updates to up to 18,000 customers.
- No rollback protection: attackers re-serve an old, vulnerable but genuinely signed version.
- Disabling platform protections: turning off App Transport Security or accepting any certificate to fix a staging issue and shipping it to production.
Framework mapping
| Control | NIST SP 800-53 Rev. 5 | NIST CSF 2.0 | MITRE ATT&CK mitigation |
|---|---|---|---|
| Client verifies signed updates | SI-7, SI-7(15) Code Authentication, CM-14 | PR.PS-02 | M1045 Code Signing |
| Protected transport | SC-8 | PR.DS-02 | Not technique specific |
| Signing key management | SC-12 | PR.PS-02 | M1045 Code Signing |
| Timely, staged patch delivery | SI-2 | PR.PS-02 | M1051 Update Software |
| Build and component authenticity | SR-11, SR-4 | PR.PS-06 | Addresses T1195.002 |
Practitioner checklist
- Inventory every self-update, plug-in and content download path that can execute code.
- Serve all feeds, metadata and packages over HTTPS with no HTTP fallback.
- Verify signatures, hashes and sizes on the client before extraction, failing closed.
- Implement rollback and freeze protection with stored version state and expiring metadata.
- Separate platform signing, update signing and TLS keys; keep root keys offline and online keys in an HSM or KMS.
- Sign only from the protected release pipeline and log every signing operation.
- Use staged rollout rings with automatic halt, and roll back by shipping a higher version.
- Test tampered, old and expired updates as automated negative tests.
- Rehearse emergency key rotation at least annually.
Standards and references
- The Update Framework: TUF Specification
- The Update Framework: Project site
- Sparkle Project: Documentation
- Electron: autoUpdater API
- Electron: Updating Applications
- NIST: SP 800-53 Rev. 5
- MITRE ATT&CK: Compromise Software Supply Chain
- MITRE ATT&CK: Code Signing mitigation
Related NHI Mgmt Group resources: Electron and Desktop App Security Guide · Code Signing Security Guide · Browser Security Hardening Guide · Linux Package Signing and Repository Trust Guide