Mar 11, 2026·6 min read·3 visits
Bouncy Castle JSSE < 1.78 incorrectly falls back to IP-based hostname verification when an explicit hostname is not provided during socket initialization. Attackers can leverage DNS spoofing to perform MitM attacks by presenting a valid certificate for the spoofed IP address.
A vulnerability in the Bouncy Castle Crypto Package for Java (BCJSSE) permits adversaries to bypass TLS hostname verification. By exploiting a fallback mechanism that evaluates the peer's IP address instead of the intended hostname, an attacker capable of DNS spoofing can conduct Adversary-in-the-Middle (AitM) attacks to intercept encrypted traffic.
The Bouncy Castle Java Secure Socket Extension (BCJSSE) provider implements the cryptographic operations required for TLS connections. A structural flaw exists in how the provider manages peer endpoint identification during the TLS handshake. When the provider initializes an SSL socket without an explicit hostname declaration, it improperly constructs the peer identity using network-layer routing information.
This behavior triggers a critical failure in certificate validation (CWE-295). Applications leveraging standard Java networking APIs, such as HttpsURLConnection, frequently instantiate sockets prior to binding the target hostname. Under these conditions, the Bouncy Castle provider evaluates the server's certificate against the resolved IP address rather than the fully qualified domain name (FQDN).
The validation mechanism inspects the Subject Alternative Name (SAN) or Common Name (CN) fields of the presented certificate. Because the library queries these fields against the IP address, the endpoint verification succeeds if the server presents a certificate explicitly valid for that specific IP. This semantic disconnect between application-layer intent and network-layer validation exposes the encrypted channel to interception.
The root cause resides in the property assignment logic within the ProvSSLSocketDirect and ProvSSLSocketWrap classes. During initialization, the socket must determine the identity of the remote peer to perform standardized endpoint identification protocols. Prior to the patch, the library implemented a conditional fallback mechanism for this identity assignment.
When the socket operated in client mode and the provJdkTlsTrustNameService configuration evaluated to false, the provider accessed the underlying peerAddress object. Instead of leaving the host field unassigned, the code executed peerAddress.getHostAddress(), mapping the peerHost string variable directly to the IPv4 or IPv6 numerical address. This variable subsequently serves as the authoritative reference for TLS certificate validation.
This implementation violates RFC 2818 and RFC 6125, which mandate that endpoint identification must utilize the reference identifier provided by the application. By substituting the intended hostname with the resolved network address, the TLS trust model delegates authority to the DNS infrastructure. The security of the TLS session becomes strictly dependent on the integrity of the underlying DNS resolution process.
The remediation implemented in Bouncy Castle commit c47f6444a744396135322784b5fea1d35d46a8a7 removes the hazardous fallback logic. The engineering team restructured the conditional statements in the socket wrapper classes to explicitly enforce hostname binding or fail safely.
// Vulnerable implementation in ProvSSLSocketDirect.java
if (useClientMode && provJdkTlsTrustNameService)
{
this.peerHost = peerAddress.getHostName();
}
else
{
this.peerHost = peerAddress.getHostAddress(); // Trigger condition
}// Patched implementation
if (!useClientMode)
{
this.peerHost = peerAddress.getHostAddress();
}
else if (provJdkTlsTrustNameService)
{
this.peerHost = peerAddress.getHostName();
}
else
{
this.peerHost = null; // Secure fallback
}The modification sets this.peerHost to null when a valid hostname is unavailable in client mode. A null value prevents the endpoint verification algorithm from executing an IP-based string comparison against the certificate SAN. Additionally, the patch introduces SetHostSocketFactory.java, ensuring that the ssl.setHost(host) method executes consistently during socket configuration prior to the TLS handshake.
Exploitation of CVE-2024-34447 requires an attacker to successfully execute a DNS poisoning attack against the target client. The adversary must manipulate the client's DNS resolver to return an IP address under the attacker's administrative control. This network positioning establishes the prerequisite for the subsequent TLS protocol manipulation.
Once the client initiates the connection to the malicious IP address, the attacker's server responds to the TLS ClientHello with a valid certificate. This certificate must contain the attacker's IP address within the Subject Alternative Name (SAN) extension. Because the vulnerable Bouncy Castle library requests validation against the IP address, the endpoint identification algorithm verifies the malicious certificate successfully.
Upon successful validation, the attacker negotiates the symmetric session keys with the client. The client transmits sensitive application-layer data to the adversary, assuming a secure connection to the intended destination. The attacker can proxy this traffic to the legitimate server to maintain functional transparency while recording all plaintext data.
The vulnerability results in a total loss of confidentiality for the affected TLS session. The CVSS v3.1 vector evaluates this as CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N, reflecting the remote, unauthenticated nature of the exploit. The attacker gains the capability to decrypt, inspect, and extract sensitive payloads such as authentication tokens, session cookies, and proprietary data.
While the NVD scoring defines the integrity impact as "None," a successful Adversary-in-the-Middle position practically enables extensive integrity violations. An attacker capable of intercepting the plaintext traffic possesses the technical capability to modify HTTP requests and responses in transit. This allows for data manipulation, injection of malicious payloads into responses, or arbitrary API command execution.
The Exploit Prediction Scoring System (EPSS) assigns a probability of 0.00227 (45.10th percentile) to this vulnerability. This metric reflects the high operational complexity of executing targeted DNS poisoning on modern networks. However, in environments lacking DNSSEC or operating on untrusted physical networks, the risk vector remains highly viable.
Organizations must deploy the updated Bouncy Castle libraries to eliminate the vulnerability. The vendor issued comprehensive patches across their distribution branches. Administrators should upgrade standard Java distributions to Bouncy Castle 1.78, Long Term Support distributions to 2.73.6, and FIPS-compliant distributions to 1.0.19.
Development teams managing custom socket implementations must review their TLS instantiation code. Any manual construction of SSLSocket instances using the Bouncy Castle provider must explicitly invoke the setHost(String host) method prior to initiating the handshake. This explicit binding overrides any internal fallback logic and guarantees validation against the correct domain name.
Infrastructure teams should enforce DNSSEC across internal and external resolution paths. Validating DNS responses cryptographically neutralizes the primary exploitation prerequisite by preventing the attacker from redirecting the initial network connection. Combining library updates with network-level validation provides defense-in-depth against endpoint identification bypasses.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Bouncy Castle Crypto Package (Java) Legion of the Bouncy Castle | < 1.78 | 1.78 |
Bouncy Castle (LTS) Legion of the Bouncy Castle | < 2.73.6 | 2.73.6 |
Bouncy Castle FIPS TLS (Java) Legion of the Bouncy Castle | < 1.0.19 | 1.0.19 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-295 |
| Attack Vector | Network |
| CVSS Score | 7.5 (High) |
| EPSS Score | 0.00227 |
| Exploit Status | No Public PoC |
| KEV Status | Not Listed |
The software does not validate, or incorrectly validates, a certificate.