Safeguard
DevSecOps

What is Code Signing

Code signing proves who published software and that it wasn't tampered with — but SolarWinds, CCleaner, and 3CX show signed doesn't mean safe.

Priya Mehta
DevSecOps Engineer
6 min read

Code signing is a cryptographic process that attaches a digital signature to software — an executable, script, container image, or firmware update — so that anyone downloading it can verify who published it and confirm the bytes haven't changed since. It relies on public-key cryptography: a publisher signs a hash of the artifact with a private key, and a certificate authority (CA) vouches for the identity behind that key through an X.509 certificate. When a device or operating system checks the signature and it's valid, the software runs; when the signature is missing, broken, or from an untrusted source, the OS throws a warning or blocks execution outright. That sounds like a solved problem, but attackers have spent over a decade proving otherwise — stealing signing keys, compromising build pipelines, and using stolen certificates to make malware look legitimate. This post breaks down how code signing works, where it fails, and what modern software supply chain security programs do to compensate for its blind spots.

What is code signing?

Code signing is the practice of applying a digital signature to a piece of software using a private key, so that a corresponding public key (embedded in a certificate) can later be used to verify the software's publisher and integrity. On Windows, this is implemented through Authenticode, which Microsoft introduced in 1996; on macOS, Apple requires Developer ID signing plus notarization since Gatekeeper's rollout with macOS 10.15 in 2019; Android uses APK signing schemes (v1 through v4, with v2 added in Android 7.0 in 2016); and Linux distributions rely on GPG-signed packages and, increasingly, Sigstore's cosign for container images. In every case, the signature proves two things: the artifact came from the claimed publisher, and it hasn't been altered by anyone — including a man-in-the-middle attacker or a compromised CDN — since it was signed.

How does the signing process actually work?

Code signing works by hashing the software artifact, encrypting that hash with the publisher's private key, and packaging the resulting signature alongside a certificate that chains back to a trusted root CA. The verifier — an OS, a browser, or a Kubernetes admission controller — recomputes the hash of the received artifact, decrypts the signature using the public key in the certificate, and checks that the two hashes match. It also validates the certificate chain up to a trusted root, checks revocation status via CRL or OCSP, and, ideally, checks a trusted timestamp so the signature remains valid even after the signing certificate expires. RFC 3161 timestamping matters in practice: DigiCert, Sectigo, and other CAs commonly issue code-signing certificates with 1-to-3-year validity periods, and without a timestamp, software signed under an expired certificate stops being trusted the moment that certificate lapses.

What happens when code signing is abused or bypassed?

Code signing gets abused when attackers obtain a legitimate signing key or compromise the build system that uses it, letting malware inherit the trust of a real vendor certificate. The clearest case is SolarWinds: in the SUNBURST attack disclosed in December 2020, attackers inserted malicious code into the Orion Platform build process and had it signed with SolarWinds' own legitimate code-signing certificate, so roughly 18,000 customers installed trojanized updates that Windows treated as fully trusted. In the 2017 CCleaner incident, attackers compromised Piriform's build server and shipped a backdoored, validly signed CCleaner 5.33 update to an estimated 2.27 million users before it was caught. The 2019 "ShadowHammer" attack on ASUS Live Update pushed malware signed with two legitimate ASUS digital certificates to roughly 1 million devices. And in the 3CX supply chain attack disclosed in March 2023, the DesktopApp installer was signed with a valid 3CX certificate, letting the malicious update pass code-signing checks industry-wide. None of these attacks defeated the cryptography — they defeated the process controls around who could request a signature.

Is a signed artifact the same as a safe artifact?

No — a valid signature only proves origin and integrity, not the absence of vulnerabilities or malicious logic, which is why code signing alone has never been sufficient for supply chain security. Stuxnet, identified in 2010, used two stolen certificates from Realtek and JMicron to get its driver components trusted by Windows, despite the payload being highly malicious. A signature answers "did this come from who it claims, unmodified," not "is this code safe to run" or "does this artifact contain a vulnerable dependency." That gap is exactly why frameworks like SLSA (Supply-chain Levels for Software Artifacts, published by Google and adopted by the OpenSSF in 2021) pair signing with build provenance attestations, and why NIST SP 800-218 (the Secure Software Development Framework, finalized in February 2022) treats code signing as one control among many — alongside SBOM generation, dependency scanning, and build isolation — rather than a standalone gate.

What are the biggest risks to code signing today?

The biggest risk to code signing today is private key exposure — through stolen keys, compromised CI/CD runners, or CAs that issue certificates without adequate identity checks. In 2012, Adobe disclosed that attackers had compromised a build server and used it to sign two pieces of malware with a legitimate Adobe code-signing certificate, forcing Adobe to revoke the certificate industry-wide. Keys stored in flat files or environment variables on build agents, rather than in Hardware Security Modules (HSMs) or cloud KMS services, remain a common failure mode because they can be exfiltrated the moment a CI runner is compromised. The industry's answer has been to move toward keyless, ephemeral signing: Sigstore, launched by the Linux Foundation in March 2021 with backing from Google, Red Hat, and Chainguard, issues short-lived certificates tied to an OIDC identity (like a GitHub Actions workflow) instead of a long-lived private key sitting on disk, and logs every signature to a public, tamper-evident transparency log called Rekor.

How Safeguard Helps

Safeguard treats code signing as one signal in a larger chain of custody rather than a trust boundary on its own. Its SBOM generation and ingest capabilities let teams track which signed artifacts actually contain which components and versions, so a valid signature on an image doesn't obscure a vulnerable library underneath it. Reachability analysis then determines whether flagged vulnerabilities in that signed artifact are actually exploitable in the running application, cutting through alert noise that pure signature or CVE checks can't resolve. Griffin AI correlates signing metadata, build provenance, and dependency data to surface anomalies — like an artifact signed outside its normal pipeline or CI identity — that indicate a compromised build process similar to SolarWinds or 3CX. And where a fix is available, Safeguard's auto-fix PRs remediate the underlying vulnerable dependency directly in the source repository, so the next signed build is verifiably safer rather than just verifiably unmodified.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.