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

CVE-2026-12185: Bouncy Castle Java Keystore Vulnerability

CVE-2026-12185 is an information disclosure flaw in Bouncy Castle for Java affecting BKS/UBER keystores that allocate from untrusted lengths before integrity checks. This article covers technical details, affected versions, and mitigation.

Published:

CVE-2026-12185 Overview

CVE-2026-12185 is an unbounded memory allocation vulnerability in the Bouncy Castle for Java cryptography library. The BcKeyStoreSpi implementation, which backs the BKS and UBER keystore formats, reads length-prefixed fields from an untrusted input stream and allocates arrays of the declared size before performing the integrity check. A crafted keystore that declares an Integer.MAX_VALUE length can trigger an immediate OutOfMemoryError on KeyStore.load(). The flaw is tracked as CWE-789: Memory Allocation with Excessive Size Value and affects Bouncy Castle for Java before 1.85 and Bouncy Castle for Java LTS before 2.73.12.

Critical Impact

A crafted keystore of only a few dozen bytes can crash a Java process with an OutOfMemoryError regardless of heap size or supplied password, because the allocation occurs before the integrity MAC is verified.

Affected Products

  • Bouncy Castle for Java before 1.85
  • Bouncy Castle for Java LTS before 2.73.12
  • Any Java application using BcKeyStoreSpi to load BKS or UBER keystores from untrusted sources

Discovery Timeline

  • 2026-08-03 - CVE-2026-12185 published to NVD
  • 2026-08-04 - Last updated in NVD database

Technical Details for CVE-2026-12185

Vulnerability Analysis

The BC provider's BKS and UBER keystore implementations read length-prefixed certificate-chain, key, secret, sealed, and salt fields from the input stream. For each field, the code allocates an array of the declared size before reading the associated data, with no upper bound enforcement. Because loadStore() runs ahead of the integrity-MAC comparison, an attacker does not need to know the keystore password to trigger the allocation. Successful exploitation forces a denial of service on any Java process that loads attacker-controlled keystore data.

Root Cause

The root cause is trust in length fields read directly from the untrusted keystore stream. The parser interprets a 32-bit length value and calls new byte[len] or constructs a Certificate array of the declared count before validating either the MAC or the availability of that many bytes in the stream. Declaring a length near Integer.MAX_VALUE therefore requests roughly 2 GiB of contiguous heap before any authentication check runs, exhausting the JVM.

Attack Vector

The attack requires the victim application to call KeyStore.load() on attacker-supplied BKS or UBER data. Exploitation typically arises in applications that accept keystores as user input, process them from network locations, or ingest them as part of configuration or upload workflows. User interaction is required to supply the crafted file, but no credentials or prior access are needed.

text
<li>Weiran SHI <weiran_shi@hotmail.com> - reported unbounded array allocation
in the BKS/UBER keystore load path (OutOfMemoryError DoS from a crafted keystore),
with POC.</li>

Source: bc-java commit 7bbd7fe5 — CONTRIBUTORS.html entry acknowledging the reporter and confirming the DoS class.

Detection Methods for CVE-2026-12185

Indicators of Compromise

  • Java processes terminating with java.lang.OutOfMemoryError originating from org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi.engineLoad or related decode helpers
  • Crash dumps or heap-dump-on-OOM artifacts referencing BcKeyStoreSpi, loadStore, or certificate-chain decoding during keystore load
  • Application logs showing repeated KeyStore.load() failures immediately after processing external BKS or UBER files

Detection Strategies

  • Inventory Java applications and dependencies for bcprov-jdk* versions below 1.85, and for LTS builds below 2.73.12, using software composition analysis tooling
  • Instrument keystore-handling code paths to log the source and size of BKS and UBER inputs, flagging inputs above a reasonable threshold (for example, more than a few megabytes)
  • Alert on JVM termination events correlated with Bouncy Castle stack frames in error output

Monitoring Recommendations

  • Monitor endpoint and container telemetry for repeated JVM restarts on services that ingest keystore material
  • Track upload endpoints and file-processing pipelines for files with BKS or UBER magic bytes originating from untrusted users
  • Collect and centralize JVM error logs so that OOM signatures tied to BcKeyStoreSpi are searchable across the fleet

How to Mitigate CVE-2026-12185

Immediate Actions Required

  • Upgrade bcprov to Bouncy Castle for Java 1.85 or later, or to Bouncy Castle for Java LTS 2.73.12 or later
  • Audit application code for any path that calls KeyStore.getInstance("BKS") or KeyStore.getInstance("UBER") on data sourced from users, network peers, or shared storage
  • Restrict the maximum size of any keystore accepted from an untrusted source before it reaches KeyStore.load()

Patch Information

The fix is delivered in commit 7bbd7fe5f44132e5b6140a2914435c12430eeb3d. The certificate chain is now decoded incrementally instead of pre-allocating a Certificate array from the declared count. Every length-prefixed block is read through a fixed-size 2 MiB buffer: allocations at or below the buffer size proceed directly, while larger declared lengths are accumulated incrementally, so a truncated stream fails with EOFException after a bounded allocation rather than an OutOfMemoryError. Store-header salt lengths are bounds-checked before allocation. Both BKS and UBER load paths, the per-entry certificate and key decode helpers, and the sealed-key retrieval path are covered. See the CVE-2026-12185 wiki entry for vendor-published detail.

Workarounds

  • Avoid loading BKS or UBER keystores from untrusted or unauthenticated sources until the upgrade is applied
  • Wrap KeyStore.load() calls in a size-limited InputStream (for example, a bounded BoundedInputStream) so the stream throws before the parser can request an oversized allocation
  • Where feasible, migrate to authenticated keystore formats such as PKCS#12 for interchange with untrusted parties
bash
# Verify the installed Bouncy Castle provider version on the classpath
unzip -p /path/to/bcprov-jdk18on-*.jar META-INF/MANIFEST.MF | grep -i 'Bundle-Version\|Implementation-Version'

# Example Maven upgrade snippet
# <dependency>
#   <groupId>org.bouncycastle</groupId>
#   <artifactId>bcprov-jdk18on</artifactId>
#   <version>1.85</version>
# </dependency>

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.