CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-24122
3.70.04%

Time Travelers & Zombie Chains: Deep Dive into CVE-2026-24122 in Sigstore Cosign

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 19, 2026·7 min read·6 visits

No Known Exploit

Executive Summary (TL;DR)

Cosign checked the validity of CA chains based on the leaf certificate's issuance time rather than the signature time. This allowed expired Intermediate CAs to validly sign artifacts, provided the leaf cert was created while the parent was still alive.

A temporal logic flaw in Sigstore Cosign's certificate validation allowed expired intermediate Certificate Authorities to validate signatures if the leaf certificate was issued before the parent's expiration. While low severity for the public Sigstore infrastructure due to ephemeral certificates, this flaw exposes private PKI deployments to 'Zombie Cert' attacks.

The Hook: When Time isn't Linear

In the world of cryptography, time is usually a hard constraint. A certificate is valid from Point A to Point B. If you try to use it at Point C (where C > B), the math should scream at you. Simple, right? Well, sigstore/cosign—the darling of the secure supply chain world—decided to get a little creative with how it perceives the fourth dimension.

This vulnerability isn't your typical memory corruption or injection flaw. It's a logic bug in how X.509 certificate chains are verified. Specifically, it’s about reference times. When verifying a digital signature, you have to ask: "Was the certificate valid when this signature was made?" Cosign answered that question correctly for the leaf certificate (the one doing the signing), but it got a little confused about the parents.

Imagine verifying a driver's license. You check the expiration date on the license (the leaf). It's valid. But to trust the license, you also need to trust the DMV that issued it (the Intermediate CA). Cosign's bug is equivalent to accepting a license issued by a DMV branch that closed down three years ago, just because the branch was open on the day the license was printed. It’s a subtle distinction, but in the binary world of trust, subtle distinctions are where the exploits hide.

The Flaw: Split-Brain Validation

To understand this bug, we have to look at how X.509 validation usually works versus how it works in the context of artifact signing. In a standard TLS handshake (like HTTPS), we check if the chain is valid right now. In artifact signing, we check if the chain was valid at the time of signing. This requires passing a specific time into the verification logic.

The root cause of CVE-2026-24122 lies in a split-brain decision made during this process. When Cosign verified a signature, it effectively performed two checks with two different distinct timelines:

  1. Leaf Validation: Checked against the Signature Timestamp. "Is this leaf cert valid at the moment the signature was created?" (Correct).
  2. Chain Validation: Checked against the Leaf's NotBefore Timestamp. "Was the Intermediate CA valid at the moment this leaf was issued?" (Technically true, but insecure).

By pinning the chain validation to the NotBefore time of the leaf, Cosign ignored everything that happened to the Intermediate CA after the leaf was issued. If the Intermediate CA expired, was revoked, or simply timed out between the leaf issuance and the signature creation, Cosign wouldn't notice. It was validating the chain based on a historical snapshot, not the relevant moment of use. This created a "Zombie Window"—a period where a dead parent CA could still ostensibly support active child certificates.

The Code: Fixing the Timeline

The fix is technically simple but conceptually critical. We need to force the entire chain verification to respect the same clock: the time the signature was created (or the integratedTime from the transparency log).

Here is a simplified view of the logic change in Go's crypto/x509 usage within Cosign. The patch essentially stops using the leaf's creation time as the reference for the chain.

The Vulnerable Logic (Conceptual):

// OLD: Chain is verified against when the certificate started existing
verifyOptions := x509.VerifyOptions{
    Roots:         trustedRoots,
    Intermediates: trustedIntermediates,
    CurrentTime:   leafCert.NotBefore, // <--- THE BUG
    KeyUsages:     []x509.ExtKeyUsage{x509.ExtKeyUsageCodeSigning},
}

The Fixed Logic (Patch 3c9a736):

// NEW: Chain is verified against the actual signature timestamp
verifyOptions := x509.VerifyOptions{
    Roots:         trustedRoots,
    Intermediates: trustedIntermediates,
    CurrentTime:   signatureTimestamp, // <--- THE FIX
    KeyUsages:     []x509.ExtKeyUsage{x509.ExtKeyUsageCodeSigning},
}

The actual commit 3c9a7363f563db76d78e2de2cabd945450f3781e ensures that CurrentTime in the verification options is consistently set to the trusted timestamp of the signature. This closes the gap; if the Intermediate CA is expired at signatureTimestamp, the whole chain fails, regardless of when the leaf was born.

The Exploit: Constructing a Zombie Chain

While the CVSS is low because this requires a specific PKI setup, the exploit scenario is fascinating. An attacker needs control over an Intermediate CA that is about to expire, or a compromised key from an expired Intermediate CA (assuming revocation checks are also bypassed or the CRL is unavailable).

The Attack Recipe:

  1. Preparation: Identify a target using a private Cosign instance with a custom PKI. Public Sigstore is safe (certs only live for 10 minutes), but enterprises love long-lived certs.
  2. The Setup: You have an Intermediate CA Int-CA that expires at T=100.
  3. The Persistence: At T=90, you use Int-CA to issue a malicious Leaf Certificate Evil-Leaf. Evil-Leaf is valid from T=90 to T=200.
  4. The Death: At T=100, Int-CA expires. It is now dead. In a proper system, trust anchors derived from it should fail.
  5. The Strike: At T=150, you sign a malicious container image using Evil-Leaf. You attach a trusted timestamp for T=150.

The Execution: The victim pulls the image. Cosign v2.x checks the signature:

  • Is Evil-Leaf valid at T=150? Yes (valid until T=200).
  • Is the chain valid? Cosign checks the chain at Evil-Leaf.NotBefore (T=90). Was Int-CA valid at T=90? YES.

Cosign validates the signature. You have successfully bypassed the expiration of the Intermediate CA, allowing a compromised or deprecated key to continue signing payloads indefinitely (or until the leaf finally dies).

The Impact: Why the Low Score?

You might be wondering: "If I can bypass CA expiration, why is this only a 3.7 (Low)?" The answer lies in the ecosystem design of Sigstore. The public instance of Sigstore (used by millions of open-source projects) issues Fulcio certificates that are valid for only 10 minutes. The Intermediate CAs are long-lived.

In the public infrastructure, it is mathematically impossible for the Intermediate CA to expire during the 10-minute validity window of a leaf cert unless the Root CA is rotating keys in a very bizarre way. The window of opportunity is practically zero.

However, the story changes for Private Deployments. If your company runs an internal Sigstore stack (which many do for proprietary software) and you manage your own PKI with traditional long-lived certificates (e.g., 1-year Leafs, 2-year Intermediates), you are vulnerable. If an Intermediate CA key is leaked after it expires, an attacker could use this logic flaw to sign malware that your internal build systems will trust blindly. It essentially breaks the concept of "Forward Secrecy" for expired CA keys.

Mitigation: Closing the Loop

The remediation is straightforward, but for those managing custom PKIs, it serves as a good reminder to audit your chain validation logic.

Immediate Action: Upgrade to Cosign v3.0.5. This version enforces strict time synchronization across the entire chain. If you are using Cosign as a library in your own Go tools, you need to go get -u and rebuild.

For the Paranoid: If you cannot upgrade immediately, you must perform out-of-band verification. This means extracting the certificate and signature from the artifact and using openssl or a similar tool to verify the chain against the current time (or the timestamp time).

> openssl verify -CAfile root.pem -untrusted intermediate.pem -attime <timestamp> leaf.pem

This manual check will fail correctly where Cosign previously succeeded.

Official Patches

SigstoreOfficial Release Notes for Cosign v3.0.5

Fix Analysis (1)

Technical Appendix

CVSS Score
3.7/ 10
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N
EPSS Probability
0.04%
Top 100% most exploited

Affected Systems

sigstore/cosign < v3.0.5Internal/Private Sigstore deployments using custom PKICI/CD pipelines relying on Cosign for artifact verification

Affected Versions Detail

Product
Affected Versions
Fixed Version
sigstore/cosign
sigstore
< 3.0.53.0.5
AttributeDetail
CWE IDCWE-295
Attack VectorNetwork
CVSS v3.13.7 (Low)
ComplexityHigh
Privileges RequiredNone
Exploit StatusTheoretical / PoC

MITRE ATT&CK Mapping

T1557Adversary-in-the-Middle
Credential Access
T1588.003Obtain Capabilities: Code Signing Certificates
Resource Development
CWE-295
Improper Certificate Validation

The software does not validate, or incorrectly validates, a certificate.

Known Exploits & Detection

N/ATheoretical exploit requiring specific PKI conditions (Intermediate expiring before Leaf).

Vulnerability Timeline

Internal discovery of timestamp synchronization issues
2026-01-09
Vulnerability Disclosed (GHSA-wfqv-66vq-46rm)
2026-02-19
Cosign v3.0.5 Released with Fix
2026-02-19

References & Sources

  • [1]GHSA-wfqv-66vq-46rm Advisory
  • [2]Patch Commit Diff

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.