HIGH bleichenbacher attackcassandra

Bleichenbacher Attack in Cassandra

How Bleichenbacher Attack Manifests in Cassandra

The Bleichenbacher attack (CVE-2023-33201) is a padding oracle vulnerability in SSL/TLS implementations that allows an attacker to decrypt ciphertexts without knowing the private key by observing error responses. In Apache Cassandra, this manifests primarily through two attack surfaces: client-to-node encryption and internode encryption when using SSL/TLS.

Cassandra's native protocol (versions 4 and 5) supports optional encryption via server_encryption_options and client_encryption_options in cassandra.yaml. When configured with RSA key exchange (instead of forward-secrecy preserving Diffie-Hellman/ECDH), the TLS handshake becomes vulnerable. An attacker positioned as a man-in-the-middle can send malformed ciphertexts to the Cassandra port (default 7000 for internode, 9042 for CQL) and observe the precise error codes returned by the server's SSLContext implementation.

Specific Cassandra code paths involved include:

  • org.apache.cassandra.transport.Server: Handles TLS handshake. The unwrap() method on the SSLEngine may throw SSLException with distinct messages for "bad record MAC" (padding error) versus "decryption failed" (other issues).
  • org.apache.cassandra.security.SSLFactory: Creates the SSLContext. If configured with key_manager_factory using RSA key exchange and without use_cipher_suites enforcing AEAD (e.g., TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384), the server remains vulnerable.
  • org.apache.cassandra.auth.PasswordAuthenticator: While not directly related to TLS, if SSL is used for authentication and the authenticator returns different error messages for "invalid credentials" versus "SSL failure", it can compound the oracle.

A real-world attack scenario: An attacker intercepts a CQL connection to a Cassandra node with weak SSL config. They capture a legitimate client's ClientHello and ServerHello exchange, then repeatedly send the captured ClientKeyExchange message with modified PKCS#1 v1.5 padding. By measuring response times or parsing exact error strings from Cassandra's logs or network responses, they can eventually recover the premaster secret and derive the session keys, decrypting all traffic to that node.

Cassandra-Specific Detection

Detecting Bleichenbacher vulnerabilities in Cassandra requires examining both configuration and runtime behavior. The issue is not in Cassandra's CQL query processing but in its TLS stack configuration.

Manual Detection Steps:

  1. Inspect cassandra.yaml for client_encryption_options and server_encryption_options.
  2. Check if keystore is configured with RSA keys (e.g., keytool -list -v -keystore keystore.jks shows "RSA" in the certificate chain).
  3. Verify cipher_suites list excludes RSA key exchange suites (look for _RSA_ without ECDHE or DHE).
  4. Use openssl s_client -connect host:9042 -tls1_2 and observe the cipher suite negotiated. If it starts with TLS_RSA_ (e.g., TLS_RSA_WITH_AES_256_CBC_SHA), it is vulnerable.

Scanning with middleBrick:

middleBrick's Encryption check tests for weak TLS configurations by analyzing the server's SSL handshake behavior. When you scan a Cassandra endpoint (e.g., https://cassandra.example.com:9042), the scanner performs:

  • Cipher suite enumeration to identify RSA key exchange suites.
  • Padding oracle testing by sending crafted TLS records and comparing error responses.
  • Certificate chain analysis for key type and strength.

The scanner returns a finding if it detects either:

  • RSA key exchange cipher suites enabled.
  • Distinguishable error messages for padding failures.

Example CLI scan:

middlebrick scan cassandra.example.com:9042 --checks encryption

The JSON output will include a category Encryption with a specific finding like "TLS padding oracle vulnerability (Bleichenbacher) possible due to RSA key exchange". The remediation guidance will reference Cassandra configuration.

Cassandra-Specific Remediation

Remediation involves configuring Cassandra to use only forward-secrecy preserving cipher suites and ensuring the Java runtime uses constant-time padding error handling.

1. Enforce AEAD Cipher Suites in cassandra.yaml

Update cassandra.yaml under both client_encryption_options and server_encryption_options:

client_encryption_options:
  enabled: true
  keystore: /path/to/keystore.jks
  keystore_password: "${KEYSTORE_PASSWORD}"
  require_client_auth: false
  # Specify only ECDHE/ECDSA or DHE suites with AES-GCM or ChaCha20
  cipher_suites:
    - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
    - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
    - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
    - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256

Do not include any TLS_RSA_ or TLS_DHE_RSA_ (DHE is computationally expensive and less preferred).

2. Use EC Keys in Keystore

Generate an EC keypair and certificate:

keytool -genkeypair -alias cassandra -keyalg EC -keysize 256 -sigalg SHA256withECDSA \
  -dname "CN=cassandra.example.com" -validity 365 -keystore keystore.jks

Replace the existing RSA key in the keystore. This ensures the certificate's public key is EC, forcing ECDHE key exchange even if RSA cipher suites are listed (though still remove RSA suites).

3. Java System Properties for Constant-Time

Set JVM options in cassandra-env.sh to enable constant-time padding checks in the JSSE provider (Java 8u161+ and Java 11+ have this by default, but enforce it):

JVM_OPTS="$JVM_OPTS -Djdk.tls.disabledAlgorithms=SSLv3,TLSv1,TLSv1.1,RSA keyExchange \
  -Dcom.sun.net.ssl.enableECC=true \
  -Dcom.sun.crypto.provider.SunJCE=true"

The RSA keyExchange in disabledAlgorithms removes RSA key exchange from the default enabled list, but explicit cipher_suites in Cassandra config takes precedence.

4. Verify with middleBrick and OpenSSL

After restarting Cassandra, re-scan with middleBrick. Also verify with:

openssl s_client -connect cassandra.example.com:9042 -tls1_2 -cipher 'ALL' | grep "Cipher is"

Output should show only ECDHE suites (e.g., ECDHE-RSA-AES256-GCM-SHA384). No TLS_RSA_ should appear.

5. Rotate Keys if Compromised

If the server was previously vulnerable, assume all past session keys could be derived. Rotate the keystore and consider invalidating any client certificates if mutual TLS was used.

Frequently Asked Questions

Does Cassandra's default configuration include Bleichenbacher-vulnerable settings?
No. Cassandra's default cassandra.yaml does not enable client-to-node or internode encryption. When encryption is manually enabled, the default cipher_suites list is empty, meaning the JVM's default cipher suite order is used. Modern JVMs (Java 11+) default to preferring ECDHE suites, so the risk is lower. However, if an administrator explicitly sets cipher_suites to include RSA key exchange (e.g., TLS_RSA_WITH_AES_256_CBC_SHA), the vulnerability is introduced.
Can middleBrick detect Bleichenbacher in Cassandra nodes that use client certificates for authentication?
Yes. middleBrick's encryption check tests the TLS handshake itself, independent of the application-layer authentication. It sends crafted handshake messages and observes server responses. Whether the server later requests a client certificate (mutual TLS) does not affect the padding oracle test, which occurs during the initial key exchange phase. The scanner will still identify if RSA key exchange is used or if error messages leak padding validity.