CVE-2026-59639 is a high severity signature bypass in Bouncy Castle for Java. CMSSignedData.verifySignatures returns true for a SignedData structure with zero signers, so unsigned content can pass. Fixed in 1.85, LTS 2.73.12 and bcpkix-fips 1.0.12, 2.0.12 and 2.1.12. Check your own signer logic too.
What's affected
- Bouncy Castle for Java: before 1.85.
- Bouncy Castle for Java LTS: before 2.73.12.
- Bouncy Castle FIPS: before bcpkix-fips 1.0.12 (1.0.X), 2.0.12 (2.0.X) and 2.1.12 (2.1.X).
- Platform: Java 8 and later.
- Who is exposed: applications that treat a true result from verifySignatures as proof of authenticity without separately checking that an expected signer is present.
How to check if you're exposed
Find which Bouncy Castle artifacts and versions your build resolves, including indirect ones.
mvn dependency:tree -Dincludes=org.bouncycastle
./gradlew dependencies --configuration runtimeClasspath | grep -i bouncycastle
Look for artifacts such as bcprov, bcpkix, bcpg and bctls, and compare the version with the fixed versions above. Check shaded or fat jars and container images as well, because Bouncy Castle is often bundled inside other libraries and a copy can hide there.
The part that decides your exposure is in your own code. Search for verifySignatures and for code that reads getSignerInfos(). If a true result alone makes you trust the content, you are exposed on affected versions. If you also confirm that a specific, expected signer certificate produced a signature, you were already protected against this case.
What to do now
- Upgrade to Bouncy Castle 1.85, LTS 2.73.12, or the fixed FIPS artifact listed above.
- Add an explicit check that the signer set is not empty, and that the signer matches the certificate or key you expect, so you are safe on any library version.
- Review every place that accepts CMS or PKCS#7 content: software update checks, signed configuration, document signing and S/MIME handling.
- Add a test that feeds a SignedData with no signers and expects rejection.
- Run the free in-browser dependency scan on your lockfile or manifest to see every affected package in one pass.
Why it matters
The weakness is CWE-347 (Improper Verification of Cryptographic Signature). The project advisory explains that the method loops over the signers and returns true once the loop finishes. RFC 5652 permits a degenerate SignedData with an empty signer set, and nothing in the library rejected it. An empty loop therefore returns true.
The result is that an attacker can submit a blob with any content and no signers, and a naive caller will accept it as signed. The integrity impact is the point: the record scores it 7.5 (High) with no confidentiality or availability impact. The record does not mark it as exploited in the wild.
Quick check
Is my app affected if I check the signer certificate myself?
The advisory says the risk is for callers who treat the true return value as proof of authenticity without separately asserting that an expected signer is present. Pinning the signer yourself avoids it, but upgrading is still recommended.
Sources
Last reviewed: 18 October 2026.