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

CVE-2026-58059: Bouncy Castle Information Disclosure Flaw

CVE-2026-58059 is an information disclosure vulnerability in Bouncy Castle for Java caused by quadratic-time escaping when stringifying X.500 distinguished names. This article covers technical details, affected versions, and mitigation.

Published:

CVE-2026-58059 Overview

CVE-2026-58059 is a denial-of-service vulnerability in the Bouncy Castle cryptographic library for Java. The flaw resides in the escaping routine used when stringifying X.500 distinguished names (DNs). The implementation exhibits quadratic-time complexity when processing RFC 4514 special characters or leading/trailing spaces in a Relative Distinguished Name (RDN) value. An attacker who supplies a large, crafted RDN reached through X500Name.toString(), equals(), or hashCode() can trigger CPU exhaustion. The issue is tracked under CWE-407: Inefficient Algorithmic Complexity.

Critical Impact

Remote, unauthenticated attackers can exhaust CPU resources on any Java service that parses attacker-controlled X.500 names 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 bc-fips 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-58059 published to NVD
  • 2026-08-04 - Last updated in NVD database

Technical Details for CVE-2026-58059

Vulnerability Analysis

The vulnerability affects the IETFUtils class in Bouncy Castle's ASN.1 X.500 style package. When the library converts an RDN value to its RFC 4514 string form, it escapes special characters such as ,, +, ", \, <, >, ;, #, and leading/trailing spaces. The pre-patch implementation performed each escape by inserting a backslash into the same StringBuilder it was actively scanning. Each insertion shifts subsequent characters, producing O(n) work per escape and O(n²/2) total work for a value containing n special characters.

Any caller that invokes X500Name.toString(), equals(), or hashCode() on attacker-controlled input reaches the vulnerable path. This includes TLS certificate parsing, CMS/PKCS#7 message handling, and general X.509 processing. The attack requires no authentication and no user interaction.

Root Cause

The root cause is an inefficient in-place mutation pattern in the escape routine. Inserting into a buffer during a linear scan turns each of the n insertions into an O(n) memory move. Submitting an RDN with tens or hundreds of thousands of special characters or padding spaces forces the JVM thread into sustained CPU work.

Attack Vector

An attacker delivers a crafted X.509 certificate, PKCS#10 CSR, CMS message, or any protocol payload containing an oversized RDN. Once the receiving Java application stringifies, compares, or hashes the parsed name, the vulnerable escape loop consumes CPU proportional to the square of the RDN length, blocking the worker thread.

java
            }
        }

-        int end = vBuf.length();
-        int index = 0;
+        // Escape in a single linear pass into a fresh builder. The previous implementation escaped by
+        // inserting a backslash into the buffer it was scanning (O(n) per insert), so a value of n
+        // RFC 4514 special characters - or n leading/trailing spaces - cost ~n^2/2 character moves: a
+        // CPU-exhaustion vector for an attacker-supplied large RDN reached via
+        // X500Name.toString()/equals()/hashCode(). Output is unchanged.
+        int len = vBuf.length();
+
+        // A leading "\#" (produced above when the value begins with '#') is emitted verbatim and the
+        // leading-space escaping is suppressed, matching the original phase ordering.
+        boolean hashPrefix = len >= 2 && vBuf.charAt(0) == '\\' && vBuf.charAt(1) == '#';

+        int firstNonSpace = 0;
+        while (firstNonSpace < len && vBuf.charAt(firstNonSpace) == ' ')
+        {
+            firstNonSpace++;
+        }
+        int lastNonSpace = len - 1;
+        while (lastNonSpace >= 0 && vBuf.charAt(lastNonSpace) == ' ')
         {
-            index += 2;
+            lastNonSpace--;
         }

-        while (index != end)

Source: bc-java commit 7bf20ee — the patch rewrites the escape routine to build a fresh buffer in a single linear pass, preserving identical output while eliminating the quadratic memory-move behavior.

Detection Methods for CVE-2026-58059

Indicators of Compromise

  • Sustained high CPU utilization on JVM threads that terminate inside org.bouncycastle.asn1.x500.style.IETFUtils.escape or callers of X500Name.toString().
  • Inbound X.509 certificates, CSRs, or CMS payloads containing RDN attribute values with unusually large runs of special characters or leading/trailing spaces.
  • Application response-time degradation correlated with TLS handshakes or certificate ingestion.

Detection Strategies

  • Inventory Java applications and dependencies to identify Bouncy Castle versions below 1.85, LTS 2.73.12, or FIPS 1.0.2.7 / 2.0.2 / 2.1.3.
  • Deploy thread-level CPU sampling and flame graphs to detect hot paths within IETFUtils escape logic.
  • Add WAF or reverse-proxy rules limiting the size of PEM-encoded certificates and CSRs accepted at the network edge.

Monitoring Recommendations

  • Alert on individual JVM threads exceeding a defined CPU budget while processing certificate or LDAP payloads.
  • Log and rate-limit endpoints that accept client certificates or CSRs from untrusted sources.
  • Track dependency SBOM changes to confirm Bouncy Castle upgrades reach every deployed service.

How to Mitigate CVE-2026-58059

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 (BC-FJA) to 1.0.2.7, 2.0.2, or 2.1.3 depending on the deployed series.
  • Enforce maximum size limits on X.509 certificates, CSRs, and CMS payloads accepted from untrusted sources.

Patch Information

The fix is committed in bc-java commit 7bf20ee and documented in the Bouncy Castle CVE-2026-58059 advisory. The patch rewrites the escape routine to perform a single linear pass into a fresh StringBuilder, keeping the emitted string identical while eliminating the O(n²) memory-move cost.

Workarounds

  • Restrict inbound RDN attribute value lengths at the application layer before invoking Bouncy Castle name-parsing APIs.
  • Isolate certificate parsing to bounded worker pools or separate processes with strict CPU quotas to contain thread-level exhaustion.
  • Where feasible, avoid calling X500Name.toString(), equals(), or hashCode() on names derived from untrusted input until upgrades complete.
bash
# Verify the deployed Bouncy Castle version in a Java project
mvn dependency:tree | grep -Ei 'bcprov|bctls|bcpkix|bc-fips'
# Example expected post-patch output:
#   org.bouncycastle:bcprov-jdk18on:jar:1.85:compile

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.