Skip to main content
All fixes

SSL, TLS, security headers

Disable TLS 1.0 and TLS 1.1 to meet PCI-DSS and modern standards

TLS 1.0 and 1.1 are deprecated since 2020 and fail PCI scans. Enforce TLS 1.2 minimum, prefer TLS 1.3, and remove SSLv3 entirely.

What's happening

TLS 1.0 (RFC 2246, 1999) and TLS 1.1 (RFC 4346, 2006) are deprecated as of RFC 8996 (2021). Both protocols rely on weak primitives (MD5, SHA1) for parts of the handshake, lack AEAD cipher modes, and are vulnerable to attacks like BEAST, Lucky13, and POODLE-on-TLS. Browsers (Chrome, Firefox, Safari, Edge) all removed support in 2020.

A server that still advertises TLS 1.0 or 1.1 is exposed to downgrade attacks: an active network attacker can strip TLS 1.2/1.3 from the ClientHello and force the connection onto the weak protocol. Even without an active attack, the configuration fails PCI-DSS scans and most modern compliance frameworks.

The fix is to set the minimum TLS version to 1.2 in your web server config, ideally also enabling TLS 1.3. SSLv2 and SSLv3 must be disabled too — they are far worse than TLS 1.0.

Why it matters

PCI-DSS 3.2.1 has prohibited TLS 1.0 since June 2018; 4.0 prohibits 1.1 too. ASV scanners (Trustwave, Qualys, SecurityMetrics) issue immediate non-compliance findings on any cardholder-environment host that accepts TLS 1.0 or 1.1.

SSL Labs grades a server with TLS 1.0/1.1 enabled at C or below. Mozilla Observatory penalizes the configuration. Bug-bounty programs file these as medium-severity issues.

Government and regulated-industry contracts (FedRAMP, HIPAA-aligned procurement, UK Cyber Essentials) require TLS 1.2 minimum. Failing the protocol-version check disqualifies the system.

Common causes

  • Default cipher and protocol list inherited from an older Linux distribution.
  • Custom SSLProtocol or ssl_protocols line that included TLSv1 and TLSv1.1 for legacy client compatibility.
  • Hardware load balancer firmware predates TLS 1.2 and was never upgraded.
  • Java application server with sslEnabledProtocols set to a permissive default.
  • CDN configuration toggle for 'allow legacy clients' was never disabled.

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 Checker

How to fix it

  1. 1

    Confirm which protocol versions the server accepts

    Run nmap --script ssl-enum-ciphers -p 443 example.com or testssl.sh example.com. The output lists every protocol version the server agrees to. Anything below TLS 1.2 must be disabled.

  2. 2

    Restrict protocols in nginx

    Set ssl_protocols TLSv1.2 TLSv1.3; in the http or server block. Do not list TLSv1 or TLSv1.1. Do not list SSLv2 or SSLv3 — they should never appear. Reload nginx with sudo nginx -t && sudo systemctl reload nginx.

  3. 3

    Restrict protocols in Apache

    Set SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 (or explicitly SSLProtocol TLSv1.2 TLSv1.3. Reload with sudo apachectl -t && sudo systemctl reload apache2. The negative-list form is forgiving against future protocol additions.

  4. 4

    Restrict protocols on a load balancer

    AWS ALB and CloudFront expose a security policy dropdown — pick one labeled 'TLS-1-2-2021' or newer. Cloudflare has an SSL/TLS → Edge Certificates → Minimum TLS Version setting; set to 1.2. Update Azure Front Door or GCP load balancer security policies the same way.

  5. 5

    Re-scan and confirm

    Re-run nmap --script ssl-enum-ciphers and confirm only TLS 1.2 and 1.3 are negotiable. Run an SSL Labs test (ssllabs.com/ssltest) — the grade should rise to A or A+. PCI scanners need a fresh run after the change.

  6. 6

    Watch for legacy-client breakage

    Monitor logs and customer support tickets after the change for clients failing to connect. The known pain points are old Android (<5.0), Windows XP, Java 6, and very old IoT devices. The right answer is almost always to upgrade those clients, not to re-enable broken TLS.

Example

ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;

Modern TLS protocol restriction in nginx

Frequently asked

Effectively zero on the public web. Cloudflare and Mozilla telemetry put TLS 1.0 below 0.1% of handshakes. Anyone still on TLS 1.0/1.1 is running unsupported software with known CVEs unrelated to TLS — keeping the server compatible with them helps no one.

Most enterprises stick at 1.2-minimum because some payment terminals and embedded devices have not migrated. Pure 1.3-only is fine for new public APIs and consumer apps where you control the clients. Test with your real client mix before committing.

Related fixes