On 6 August 2026 the Sigstore project published GHSA-fx35-mq7g-6g98, a High severity advisory (CVSS 7.4) titled "Verification bypass via public key in legacy bundle", and shipped fixes in Cosign v3 3.1.3 and v2.6.5. When a legacy JSON bundle carried a bare public key where a certificate should be, cosign verify-blob skipped the identity checks and still printed Verified OK. Teams that verify release archives, binaries or SBOM files with keyless signing are the ones to look at.
What's affected
The advisory is specific about scope:
- Affected:
cosign verify-blobandcosign verify-blob-attestationwhen given a legacy JSON bundle. Cosign v3 up to and including 3.1.2 (fixed in v3.1.3), and Cosign v2 up to and including 2.6.4 (fixed in v2.6.5). - Not affected: container image verification with
cosign verifyandcosign verify-attestation, and verification that uses the standardized Sigstore protobuf bundle format, which is the default in Cosign v3.
The root cause was a silent fallback. If the cert field of a legacy bundle failed to parse as an X.509 certificate, Cosign loaded the contents as a raw public key. Once that verifier was set, certificate chain validation and policy checks were skipped, so the certificate identity and OIDC issuer flags were ignored. The signature only had to be valid for the key the attacker supplied. The advisory adds a second effect: a key passed with the key flag could be overwritten by the key inside the bundle.
How to check if you're exposed
Find the version first, on every runner and developer machine:
cosign version
Then search your repositories, CI definitions and install scripts for blob verification:
grep -rEn "verify-blob(-attestation)?" .github .gitlab-ci.yml scripts Makefile Dockerfile 2>/dev/null
For each hit, check what the bundle file is. A legacy bundle is a JSON file with a cert field. A protobuf bundle declares its media type as application/vnd.dev.sigstore.bundle+json. Look at the file your pipeline downloads:
jq 'keys' artifact.bundle.json
jq -r '.mediaType // "no mediaType (likely legacy)"' artifact.bundle.json
Downloaded bundles are attacker-influenced input in exactly the case this advisory describes, so inspect them before trusting any pipeline that fetches a bundle from the same place as the artifact.
What to do now
- Upgrade Cosign to v3.1.3, or v2.6.5 if you are still on the v2 line. Pin the version in your install step.
- If you install Cosign in GitHub Actions or another CI system, pin the installer by commit or checksum, not a moving tag.
- Move blob signatures to the protobuf bundle format. The advisory names this as the workaround, and
cosign bundle createaccepts an old format bundle and writes a new one:
cosign bundle create --bundle old.bundle.json --artifact release.tar.gz --out release.sigstore.json
Check the help output of cosign bundle create for the exact flags your installed version expects.
- Re-verify with explicit identity and issuer, using the form shown in the Sigstore docs:
cosign verify-blob release.tar.gz --bundle release.sigstore.json \
--certificate-identity=name@example.com \
--certificate-oidc-issuer=https://accounts.example.com
- Re-run verification for artifacts you consumed during the exposure window if the bundle came from a source you do not control.
The release notes for v3.1.2 also say that release may be the last v3.1 version before work on Cosign v4, and encourage moving to the bundle format supported since v2.6. Treat that as the migration signal.
How this could have been avoided
- Use the protobuf bundle format. The advisory says its verification engine is not affected. Teams that had already migrated were never exposed.
- Pin both identity and issuer, then test that the pin bites. Add a negative test to CI: verify a known artifact with a wrong identity and require a non-zero exit code. A bypass of this kind turns that test red.
- Keep your verifier current. A version check in CI that fails when Cosign is older than your minimum catches this class quickly.
- Verify by digest, from a location you control. Do not fetch the artifact and its bundle from the same unauthenticated place and trust whatever arrives.
- Log the identity and issuer you enforced. A wrapper script that prints both makes a missing assertion visible in review.
Why it matters
Signature verification is a security control, and controls need tests like any other code. This bug was not a broken algorithm. It was a fallback path that treated a parse failure as permission to try a weaker mode.
The failure mode is also worth remembering for your own tooling: when a strict check cannot run, fail closed and say why. A tool that quietly downgrades is worse than one that errors.
Try it yourself
Write a small script that runs your real verify command once with the correct identity and once with a deliberately wrong one, and fail the build unless the first passes and the second fails. Run it on every Cosign upgrade. Then see how build provenance and attestations fit together.
Click through it at your own pace, or open it full screen.
Quick check
Is cosign verify on a container image affected by this advisory?
No. The advisory lists container image verification with cosign verify and cosign verify-attestation as not affected. The issue is in blob and blob attestation verification with legacy JSON bundles.
Which versions contain the fix?
Cosign v3.1.3 and v2.6.5.