DEV Community

Bryan Rafael
Bryan Rafael

Posted on

TLS hardening checklist: expiry, legacy protocols and weak ciphers (passive audit)

You don't need a scanner to catch most TLS failures. A passive review of your certificate chain and protocol negotiation finds the issues clients (and auditors) care about:

What fails a TLS review

  1. Certificate expiring in < 14 days (or already expired). Renewal must be automated — ACME clients are free.
  2. TLS 1.0 / 1.1 still accepted. Legacy protocol support is a fast-track FAIL in any serious audit (PCI-DSS banned TLS 1.0 in 2018).
  3. Weak cipher suites (< 128-bit, RC4, 3DES, CBC beasts). Modern stacks should negotiate AES-GCM/ChaCha20 only.
  4. No HSTS / short max-age: transport security is only as strong as the enforcement header.

Checking without third-party tools

Python's stdlib does all of it:

import ssl
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.check_hostname = False; ctx.verify_mode = ssl.CERT_NONE
for ver in (ssl.TLSVersion.TLSv1, ssl.TLSVersion.TLSv1_1, ssl.TLSVersion.TLSv1_2):
    ctx.minimum_version = ctx.maximum_version = ver
    try:
        with ctx.wrap_socket(connect("yoursite.com", 443), server_hostname="yoursite.com") as s:
            print(ver, "->", s.cipher())
    except Exception:
        print(ver, "-> rejected (good)")
Enter fullscreen mode Exit fullscreen mode

My reconpp CLI packages this (plus cert expiry via ssl._ssl._test_decode_cert, headers, cookies, CORS, exposed files) into one command:

pip install git+https://github.com/bryanrafaelbueno/reconpp
reconpp -u https://yoursite.com -f md -o relatorio.md
Enter fullscreen mode Exit fullscreen mode

Baseline to adopt today

  • HSTS: max-age=31536000; includeSubDomains; preload
  • TLS 1.2/1.3 only; AES-GCM/ChaCha20 ciphers
  • Automatic renewal with 30-day buffer (Let's Encrypt + ACME)

The full 70+ point checklist (transport, headers, sessions, API, auth, dependencies, CI/CD) is in my pt-BR ebook — free sample:

Top comments (0)