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. Theunwrap()method on theSSLEnginemay throwSSLExceptionwith distinct messages for "bad record MAC" (padding error) versus "decryption failed" (other issues).org.apache.cassandra.security.SSLFactory: Creates theSSLContext. If configured withkey_manager_factoryusing RSA key exchange and withoutuse_cipher_suitesenforcing 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:
- Inspect
cassandra.yamlforclient_encryption_optionsandserver_encryption_options. - Check if
keystoreis configured with RSA keys (e.g.,keytool -list -v -keystore keystore.jksshows "RSA" in the certificate chain). - Verify
cipher_suiteslist excludes RSA key exchange suites (look for_RSA_withoutECDHEorDHE). - Use
openssl s_client -connect host:9042 -tls1_2and observe the cipher suite negotiated. If it starts withTLS_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 encryptionThe 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_SHA256Do 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.jksReplace 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?
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.