SSLv3’s padding oracle vulnerability means attackers can decrypt sensitive data, a problem that became critical with POODLE and BEAST.
openssl s_client -connect example.com:443 -ssl3
If this command connects and shows a certificate, your server still supports SSLv3.
Common Causes & Fixes
1. Apache HTTP Server Configuration
- Diagnosis: Check your Apache SSL configuration file (e.g.,
/etc/httpd/conf.d/ssl.confor/etc/apache2/mods-enabled/ssl.conf). - Cause: The
SSLProtocoldirective includesSSLv3. - Fix: Remove
SSLv3from theSSLProtocoldirective. A good setting is:
This explicitly disables all protocols except TLSv1.2 and TLSv1.1, ensuring SSLv3 is off.SSLProtocol -All +TLSv1.2 +TLSv1.1 - Why it works: Apache directly controls which SSL/TLS protocols the server will negotiate with clients. Removing SSLv3 from this list prevents any SSLv3 handshake from succeeding.
2. Nginx Configuration
- Diagnosis: Examine your Nginx server block configuration file (often in
/etc/nginx/sites-available/or/etc/nginx/conf.d/). - Cause: The
ssl_protocolsdirective listsSSLv3. - Fix: Remove
SSLv3from thessl_protocolsdirective. A secure setting is:
This ensures only TLSv1.2 and TLSv1.1 are offered, excluding SSLv3.ssl_protocols TLSv1.2 TLSv1.1; - Why it works: Nginx uses
ssl_protocolsto dictate the highest and lowest TLS/SSL versions it will allow for a connection. Removing SSLv3 prevents its use.
3. HAProxy Configuration
- Diagnosis: Inspect your HAProxy configuration file (usually
/etc/haproxy/haproxy.cfg). - Cause: The
ssl-default-server-optionsor specific frontendoptionsdirective includesssl-v3. - Fix: Remove
ssl-v3from the relevantoptionsline. A secure configuration would look like this:
More commonly, you’d ensure yourfrontend my_https_frontend bind *:443 ssl crt /etc/ssl/certs/mycert.pem option ssl-server-hello http-request add-header Strict-Transport-Security "max-age=31536000;" default_backend my_backend # Ensure SSLv3 is NOT in the options # Example of what to REMOVE if present: # server-options ssl-v3 # Example of a secure setting if you were to specify protocols (less common here): # ssl-default-server-options no-sslv3binddirective doesn’t explicitly enablessl-v3and rely on the absence of it in the globalssl-default-server-optionsor specific frontendoptions. If you do specify, ensure it’sno-sslv3. - Why it works: HAProxy acts as a reverse proxy and SSL terminator. The
optionsdirective controls its SSL/TLS negotiation behavior, and disablingssl-v3prevents it from establishing such connections.
4. Load Balancer or Network Appliance Configuration
- Diagnosis: Access the management interface of your hardware or cloud load balancer (e.g., AWS ELB, F5 BIG-IP, Cloudflare).
- Cause: The SSL/TLS profile or policy applied to your listener or virtual server is configured to allow SSLv3.
- Fix: Navigate to the SSL/TLS settings for your listener or virtual server and explicitly disable SSLv3. Look for options like "SSLv3 Enabled" and set it to "No" or remove it from the list of allowed protocols. For AWS ELB, choose a Security Policy that doesn’t include SSLv3 (e.g.,
ELBSecurityPolicy-TLS-1-2-2017-01). - Why it works: Load balancers often handle SSL termination. They need to be configured to disallow insecure protocols at the point of connection.
5. Application Server (Tomcat, Jetty, etc.) Configuration
- Diagnosis: Check the
server.xml(Tomcat) or equivalent configuration file for your application server. - Cause: The
sslProtocolorprotocolsattribute in the SSL/TLS connector is set to includeSSLv3. - Fix: Remove
SSLv3from the connector’s protocol attribute. For Tomcat:
This explicitly sets the allowed protocols to TLSv1.2 and TLSv1.1.<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLSv1.2,TLSv1.1"> <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" /> </Connector> - Why it works: The application server is directly responsible for its own SSL/TLS negotiation when it’s the endpoint. Modifying the connector configuration tells the server’s embedded SSL/TLS engine not to offer or accept SSLv3.
6. Client-Side Libraries or Applications
- Diagnosis: If you’re seeing this error from an application you control (e.g., a script making API calls), check its underlying SSL/TLS library.
- Cause: The application is configured to try SSLv3, or its default library settings are outdated. This is less common for direct server configuration but can happen with custom clients.
- Fix: Update the library (e.g.,
requestsin Python,OpenSSLbindings) or explicitly configure it to use modern TLS versions. Forrequestsin Python, ensure you’re using a recent version which defaults to TLSv1.2. If you need to force it:import ssl import requests # Create a TLS context that only allows TLSv1.2 context = ssl.create_default_context() context.minimum_version = ssl.TLSVersion.TLSv1_2 context.maximum_version = ssl.TLSVersion.TLSv1_2 try: response = requests.get('https://example.com', verify=True, ssl_context=context) print(response.status_code) except requests.exceptions.SSLError as e: print(f"SSL Error: {e}") - Why it works: The client’s SSL/TLS context is being explicitly restricted to only negotiate TLSv1.2, preventing any attempt to fall back to SSLv3.
After disabling SSLv3, you’ll likely encounter errors related to older clients that only support SSLv3 (e.g., Internet Explorer on Windows XP). You’ll need to manage those exceptions or encourage upgrades.