The BEAST (Browser Exploit Against SSL/TLS) attack leverages weaknesses in CBC-mode cipher suites, allowing attackers to decrypt portions of encrypted traffic. While modern browsers have implemented client-side mitigations, server-side cipher prioritization remains important for defense-in-depth strategies.
Contrary to common expectation, Tomcat's ciphers
attribute in server.xml
doesn't enforce strict ordering. The Java JSSE layer makes the final selection based on:
- Key strength preferences
- JVM version and provider implementation
- Client capabilities during handshake
For Tomcat 6+, we can enforce cipher priority through JVM arguments in catalina.sh
or catalina.bat
:
export JAVA_OPTS="$JAVA_OPTS -Djdk.tls.ephemeralDHKeySize=2048"
export JAVA_OPTS="$JAVA_OPTS -Djdk.tls.server.cipherSuites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"
For granular control, create a custom SSLServerSocketFactory
implementation:
public class PrioritizedCipherSSLSocketFactory extends SSLServerSocketFactory {
@Override
public String[] getDefaultCipherSuites() {
return new String[] {
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
// ... other prioritized ciphers
};
}
// Implement remaining abstract methods
}
Configure it in server.xml
:
<Connector
sslImplementationName="custom.PrioritizedCipherSSLSocketFactory"
... other attributes ...
/>
For systems using Tomcat's APR connector, modify OpenSSL configuration:
<Connector
protocol="org.apache.coyote.http11.Http11AprProtocol"
SSLEnabled="true"
SSLCipherSuite="ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:!aNULL:!MD5:!DSS"
SSLHonorCipherOrder="true"
/>
Use these tools to validate your configuration:
- OpenSSL command:
openssl s_client -connect yourdomain:443 -cipher ALL
- SSL Labs test:
https://www.ssllabs.com/ssltest/
- TestSSLServer:
java -jar TestSSLServer.jar yourdomain 443
Current best practices suggest:
- Disabling all CBC-mode ciphers in favor of AEAD modes (GCM)
- Enabling TLS 1.2+ exclusively
- Implementing certificate transparency
- Regular cipher suite rotation
The BEAST (Browser Exploit Against SSL/TLS) attack exploits a vulnerability in the CBC (Cipher Block Chaining) mode of operation in SSL/TLS. While modern browsers have implemented client-side fixes, server-side mitigation through cipher prioritization remains important for defense-in-depth strategies.
By default, Tomcat's JSSE implementation selects ciphers based on key strength rather than the order specified in server.xml
. This behavior can be verified using tools like SSL Labs' SSL Test, which shows no cipher preference for default Tomcat configurations.
For the standard HTTP connector, you'll need to implement a custom SSLContext
to enforce cipher priority. Here's a solution using a custom filter:
public class CipherPriorityFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
String[] preferredCiphers = {
"TLS_ECDHE_RSA_WITH_RC4_128_SHA",
"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
// Add other ciphers in your preferred order
};
SSLContext context = SSLContext.getDefault();
SSLEngine engine = context.createSSLEngine();
engine.setEnabledCipherSuites(preferredCiphers);
}
// Other filter methods...
}
The APR connector offers more granular control through OpenSSL configuration. In your server.xml
:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
SSLEnabled="true"
SSLCipherSuite="ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:RSA-RC4-SHA:RSA-RC4-MD5:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK"
SSLHonorCipherOrder="true"
... />
While prioritizing RC4 was a common BEAST mitigation, modern recommendations suggest:
- Disabling RC4 completely due to newer vulnerabilities
- Using TLS 1.2+ with AEAD ciphers like AES-GCM
- Implementing perfect forward secrecy (PFS)
Here's a modern cipher suite configuration for Tomcat 8.5+:
sslEnabledProtocols="TLSv1.2"
ciphers="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,
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
Always test your configuration using:
- SSL Labs' SSL Test (https://www.ssllabs.com/ssltest/)
- OpenSSL command:
openssl s_client -connect yourdomain:443 -cipher
- Java's built-in tools:
jdk.tls.disabledAlgorithms
in java.security file