Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-13506

CVE-2026-13506: Bouncy Castle ASN.1 Parsing Vulnerability

CVE-2026-13506 is an ASN.1 parsing flaw in Bouncy Castle for Java that resets nesting-depth guards during lazy sequence forcing. This article covers technical details, affected versions, impact, and mitigation.

Published:

CVE-2026-13506 Overview

CVE-2026-13506 affects Bouncy Castle for Java, a widely deployed cryptographic library. The vulnerability resides in the lazy Abstract Syntax Notation One (ASN.1) sequence parsing path. Forcing a LazyEncodedSequence resets the nested-construction depth guard, defeating the StreamUtil depth limit. An attacker can submit a crafted ASN.1 structure with deeply nested SEQUENCE elements. A whole-tree walk of that input triggers a StackOverflowError, causing a denial of service in any application parsing untrusted ASN.1 data.

Critical Impact

Remote, unauthenticated attackers can crash Java applications that parse untrusted ASN.1, X.509, or Cryptographic Message Syntax (CMS) data using vulnerable Bouncy Castle versions.

Affected Products

  • Bouncy Castle for Java before 1.85
  • Bouncy Castle for Java LTS before 2.73.12
  • Bouncy Castle for Java FIPS (BC-FJA) before 1.0.2.7 (1.0.X), 2.0.2 (2.0.X), and 2.1.3 (2.1.X)

Discovery Timeline

  • 2026-08-03 - CVE-2026-13506 published to the National Vulnerability Database (NVD)
  • 2026-08-04 - Last updated in NVD database

Technical Details for CVE-2026-13506

Vulnerability Analysis

The flaw is an uncontrolled recursion issue [CWE-674] in the ASN.1 parser. Bouncy Castle uses a depth guard in StreamUtil to prevent unbounded nested-construction recursion. When a SEQUENCE is captured lazily as a LazyEncodedSequence, calling force() initiates a fresh parse. The prior implementation of LazyConstructionEnumeration created a new ASN1InputStream without carrying the current depth counter. Each level of nested lazy parsing therefore reset the guard to the configured maximum. A traversal of the parsed tree recursed unbounded and exhausted the JVM stack.

Root Cause

The root cause is state loss across parser continuations. The LazyConstructionEnumeration constructor accepted only the encoded bytes and rebuilt an ASN1InputStream with default depth, discarding the remaining-depth counter from the outer parse. The depth guard was scoped per stream rather than per parse tree.

Attack Vector

The attack requires no authentication or user interaction. Any endpoint that accepts and parses ASN.1-encoded input, including X.509 certificates, CMS envelopes, PKCS#7 messages, or Certificate Signing Requests (CSRs), is a candidate. An attacker supplies a payload with SEQUENCE nesting deeper than the stack tolerates, then triggers a full tree walk to raise a StackOverflowError.

java
// Security patch: core/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java
// Enforce nested-construction depth guard on the lazy ASN.1 sequence parse path
         this(new ByteArrayInputStream(input), input.length, lazyEvaluate);
     }
 
+    /**
+     * Continue a lazily-deferred parse at a specific remaining nesting depth, so that forcing a
+     * LazyEncodedSequence keeps decrementing the nested-construction guard instead of resetting it
+     * to the configured maximum. Without this a deeply nested SEQUENCE captured lazily would parse
+     * one level per force() with the depth reset each time, defeating the StreamUtil depth limit
+     * and allowing a StackOverflowError on a whole-tree walk of crafted input.
+     */
+    ASN1InputStream(byte[] input, boolean lazyEvaluate, int depth)
+    {
+        this(new ByteArrayInputStream(input), depth, input.length, lazyEvaluate, new byte[16]);
+    }

Source: Bouncy Castle security commit 77454da

java
// Security patch: core/src/main/java/org/bouncycastle/asn1/LazyConstructionEnumeration.java
// Propagate the remaining depth counter into the nested parse
     private ASN1InputStream aIn;
     private Object          nextObj;
 
-    public LazyConstructionEnumeration(byte[] encoded)
+    public LazyConstructionEnumeration(byte[] encoded, int depth)
     {
-        aIn = new ASN1InputStream(encoded, true);
+        aIn = new ASN1InputStream(encoded, true, depth);
         nextObj = readObject();
     }

Source: Bouncy Castle security commit 77454da

Detection Methods for CVE-2026-13506

Indicators of Compromise

  • StackOverflowError exceptions traced through org.bouncycastle.asn1.ASN1InputStream or LazyEncodedSequence.force() in application logs.
  • Repeated JVM crashes or worker restarts correlated with inbound requests carrying ASN.1, X.509, or CMS payloads.
  • Inbound certificates or PKCS#7 blobs with unusually deep SEQUENCE nesting relative to normal traffic baselines.

Detection Strategies

  • Inventory Java applications and dependencies for bcprov-jdk*, bc-lts, and bc-fips artifacts below the fixed versions using Software Composition Analysis (SCA) tooling.
  • Instrument ASN.1 parsing entry points to log parser depth and payload size, alerting on anomalous values.
  • Deploy runtime application self-protection or Web Application Firewall (WAF) rules that reject certificate and PKCS#7 payloads exceeding size and nesting thresholds.

Monitoring Recommendations

  • Monitor JVM crash telemetry and unhandled exception counters for spikes in StackOverflowError.
  • Track service availability metrics for TLS terminators, signature verifiers, and CMS processors that consume external input.
  • Alert on repeated malformed-ASN.1 parse failures from a single source IP, indicating probing.

How to Mitigate CVE-2026-13506

Immediate Actions Required

  • Upgrade Bouncy Castle for Java to 1.85 or later.
  • Upgrade Bouncy Castle for Java LTS to 2.73.12 or later.
  • Upgrade Bouncy Castle for Java FIPS to 1.0.2.7, 2.0.2, or 2.1.3 depending on the deployed series.
  • Rebuild and redeploy all applications, containers, and shaded JARs that embed the vulnerable library.

Patch Information

The fix propagates the remaining nesting-depth counter into LazyConstructionEnumeration and adds an ASN1InputStream constructor that continues a lazily-deferred parse at a specific depth. This ensures force() decrements the guard instead of resetting it. See the Bouncy Castle CVE-2026-13506 advisory and the upstream commit 77454da.

Workarounds

  • Enforce strict size limits on inbound ASN.1, X.509, and CMS payloads at the network edge or reverse proxy.
  • Validate certificate and message structure with an alternative parser before handing input to Bouncy Castle.
  • Isolate ASN.1 parsing into a supervised worker process that restarts cleanly on StackOverflowError to preserve service availability.
bash
# Maven: pin patched Bouncy Castle versions
mvn dependency:tree -Dincludes=org.bouncycastle | grep -E 'bcprov|bc-lts|bc-fips'

# Example pin in pom.xml
# <dependency>
#   <groupId>org.bouncycastle</groupId>
#   <artifactId>bcprov-jdk18on</artifactId>
#   <version>1.85</version>
# </dependency>

# Gradle: verify resolved versions
./gradlew dependencies --configuration runtimeClasspath | grep bouncycastle

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.