SSL, TLS, security headers
Disable weak SSL ciphers and enforce modern TLS suites
Your server still negotiates RC4, 3DES, or CBC ciphers that fail PCI scans and SSL Labs grades B or below. Enforce ECDHE-AES-GCM and ChaCha20-Poly1305 only.
What's happening
Weak ciphers are TLS cipher suites whose primitives — block cipher, mode of operation, MAC, or key exchange — are known to be broken or to provide insufficient security margin in 2026. RC4 is broken. 3DES is meet-in-the-middle attackable and fails the SWEET32 birthday bound. Static RSA key exchange has no forward secrecy. CBC modes paired with HMAC are vulnerable to Lucky13 and padding oracle attacks if not implemented in constant time.
When a server advertises these suites in its ServerHello, scanners (Qualys SSL Labs, Mozilla Observatory, internal PCI scanners) flag the configuration. The connection itself usually works because the client picks the strongest mutually supported suite, but a misconfigured client or a downgrade attack can still land on the weak option.
The fix is to restrict the server's cipher list to suites built on ECDHE key exchange, AEAD modes (GCM or ChaCha20-Poly1305), and SHA-256 or better. On TLS 1.3 this is automatic — every TLS 1.3 suite is AEAD with forward secrecy. On TLS 1.2 you must explicitly remove the weak suites.
Why it matters
Failed PCI-DSS scans block your card-processing certification. Trustwave, SecurityMetrics, and Qualys ASV scanners all reject 3DES and RC4 outright since 2018; the scan report lists every site as non-compliant and the merchant cannot transact until fixed.
SSL Labs grades drop to B or below, which is publicly visible to anyone who runs the test. Bug-bounty hunters and security-conscious customers use this as a smell test.
Weak suites enable downgrade attacks (FREAK, Logjam, BEAST). A nation-state or coffee-shop attacker who can MITM the handshake can force the connection onto the weak suite and break it offline.
Common causes
- Default OS cipher lists from older Linux distributions still include 3DES and RC4.
- Custom
ssl_ciphersline copied from a 2014 blog post and never reviewed. - TLS 1.2 enabled with no explicit cipher restriction, defaulting to OpenSSL's HIGH list which includes weak options.
- Hardware load balancers running firmware older than the cipher's deprecation date.
- Java application servers (Tomcat, Jetty) with default JSSE cipher lists.
Detect this on your site
Run a quick scan with the SSL Checker. The tool surfaces this exact issue with the records and context needed to apply the fix below.
Open SSL CheckerHow to fix it
- 1
Enumerate negotiable cipher suites
Run
nmap --script ssl-enum-ciphers -p 443 example.com. The output groups suites by TLS version and grades each one. Anything graded C, D, or E should be removed. Alternatively usetestssl.sh example.comfor a more detailed report. - 2
Adopt the Mozilla intermediate profile
Mozilla publishes maintained TLS configurations at ssl-config.mozilla.org. Pick the 'intermediate' profile unless you have a specific reason for 'modern' (which drops TLS 1.2 entirely). The generator outputs nginx, Apache, HAProxy, and AWS configurations directly.
- 3
Apply the cipher list to nginx
Set
ssl_protocols TLSv1.2 TLSv1.3;andssl_ciphersto the Mozilla intermediate list. Also setssl_prefer_server_ciphers off;— modern advice flipped on this; with TLS 1.3 client preference is fine because every suite is strong. - 4
Apply the cipher list to Apache
In Apache use
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1andSSLCipherSuiteset to the Mozilla intermediate string. AddSSLHonorCipherOrder offfor the same reason. Reload withsudo apachectl -t && sudo systemctl reload apache2. - 5
Restart and re-scan
Reload the server and re-run the nmap or testssl.sh scan. Confirm only TLS 1.2 and TLS 1.3 are negotiable, with AEAD suites only. PCI scanners will need a fresh run; SSL Labs caches its grade for 24 hours but you can force a refresh from the test page.
- 6
Lock the configuration in version control
Commit the cipher line into your infrastructure repo and add a CI check that fails if the line drifts. Cipher recommendations evolve — set a calendar reminder to re-review against Mozilla's profile every 12 months.
Example
ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; ssl_session_tickets off;
Mozilla intermediate cipher profile for nginx
Frequently asked
Yes with a strict AEAD-only cipher list and no static RSA key exchange. Mozilla's intermediate profile keeps TLS 1.2 specifically because some payment terminals and IoT devices have not migrated. Drop to TLS 1.3-only when your client telemetry shows you can.
Renegotiation has been deprecated; OpenSSL since 1.0.2 only allows secure renegotiation per RFC 5746. There is no separate switch needed. If you see scanner findings about renegotiation they are usually about TLS 1.0 — disabling 1.0 fixes both.
Related fixes
SSL, TLS, security headers
Disable TLS 1.0 and TLS 1.1 to meet PCI-DSS and modern standards
SSL, TLS, security headers
Replace weak Diffie-Hellman parameters with 2048-bit or larger
SSL, TLS, security headers
Mitigate the CRIME TLS compression attack on web servers
SSL, TLS, security headers
Eliminate POODLE risk by disabling SSLv3 and CBC fallback