open atlas
↑ Back to track
Security Foundations SECF · 04 · 01

TLS in depth

A valid padlock only proves the channel is encrypted and the server authenticated right now. Whether that protection survives a stolen key, an active downgrade, or a plaintext first hop depends on forward secrecy, a minimum protocol version, and HSTS.

SECF Middle ◷ 16 min
Level
FoundationsJuniorMiddleSenior

A backup of your API server’s private key turns up in a public bucket. Annoying, but you rotate the key, revoke the cert, and move on — the breach is contained, you tell the room. Then a researcher emails you a decrypted transcript of a request one of your customers made three months ago: their bearer token, in cleartext, pulled from traffic captured long before the leak. Nobody touched your server back then. The attacker simply recorded the ciphertext and waited. Your TLS was “on” the whole time — valid cert, green padlock — and it still handed over months of history the instant one long-term key escaped. The padlock was never the whole story.

By the end of this lesson you’ll know what a valid TLS connection actually guarantees, why forward secrecy decides whether a stolen key leaks the past, how a downgrade attack defeats “we ordered strong ciphers first,” and why SSL stripping is the one gap no cipher can close.

What the handshake actually establishes

A TLS connection does three jobs at once, and conflating them is the root of most TLS mistakes. It authenticates the server: the certificate, validated up a chain to a trusted root, proves you’re talking to the real api.example.com and not an impostor. It establishes a session key: both sides agree on symmetric keys so the rest of the conversation is encrypted. And it provides integrity: an AEAD cipher (AES-GCM, ChaCha20-Poly1305) makes tampering detectable. The green padlock means all three held at handshake time — nothing more. It says nothing about what happens to that traffic if the server’s private key is stolen tomorrow, and nothing about how the connection got started in the first place.

In TLS 1.3 (RFC 8446) the handshake is one round trip. The client sends a ClientHello listing the protocol versions and cipher suites it supports, plus a freshly generated ephemeral Diffie-Hellman public key. The server replies with its certificate, its own ephemeral DH key, and a Finished that signs the whole transcript so far. Both sides combine the two ephemeral keys to derive the session secret. The crucial detail: the long-term certificate key is used only to sign the handshake (prove identity), never to encrypt the session secret. That separation is what makes the next section possible.

Forward secrecy: does a stolen key leak the past?

Here is the single most important property, and the one the padlock hides. The question is: if an attacker steals the server’s long-term private key, can they decrypt traffic they recorded before the theft?

With RSA key transport — the old TLS ≤1.2 default — the answer is yes. The client generates the session secret, encrypts it with the server’s long-term RSA public key, and sends it. Whoever holds the matching private key can recover that session secret, forever. So an attacker who records ciphertext today and steals the key in six months decrypts everything retroactively. This is the “harvest now, decrypt later” model, and it’s exactly the incident in the hook: months of captured traffic unlocked by one leaked key.

With (EC)DHE key exchange — ephemeral Diffie-Hellman — the session secret is derived from per-connection ephemeral keys that are generated, used, and then thrown away. The long-term key only signs; it never carries the secret. After the handshake there is nothing on disk that can reconstruct that session’s key. Stealing the long-term key lets the attacker impersonate the server going forward (which rotation and revocation address), but it cannot decrypt a single recorded past session. That property is forward secrecy, and TLS 1.3 makes it mandatory — RSA key transport was removed from the protocol entirely. On TLS 1.2 you get it only if you restrict the cipher suites to ECDHE.

So “we have HTTPS and the cert is valid” is not the same claim as “our recorded traffic is safe from a future key theft.” The first is about authentication and encryption right now; the second is purely about whether every accepted suite is ECDHE. A padlock over an RSA-key-transport suite is a time bomb.

Why this works

Why was RSA key transport ever the default if it has this flaw? Because for years it was simpler and faster: the server did one private-key decryption per handshake and skipped the ephemeral DH math, which mattered when CPUs were slower and ECDHE wasn’t hardware-accelerated. Forward secrecy looked like a luxury — until “harvest now, decrypt later” stopped being theoretical (mass traffic capture, plus the looming threat that a future quantum computer or a single key leak retroactively unlocks years of archives). The cost-benefit flipped: modern CPUs make ECDHE cheap, and the downside of not having it is catastrophic and retroactive. TLS 1.3’s designers settled the debate by deleting the non-forward-secret option from the protocol.

Downgrade attacks: why “we ordered strong ciphers first” fails

A common and wrong mental model is: “our server lists the strong ECDHE-AEAD suites first in its preference order, and ssl_prefer_server_ciphers is on, so a modern client always lands on a strong suite.” Server preference order only decides the winner when both ends are negotiating honestly and mutually support several suites. It is irrelevant against an active attacker.

A downgrade attack is an active man-in-the-middle that tampers with the negotiation itself. The attacker intercepts the ClientHello and strips out the strong suites the client offered, or forces a fallback to an older protocol version. The server then sees a menu containing only the weak option — an export-grade key exchange (FREAK, Logjam) or an old CBC suite (POODLE on TLS 1.0) — and picks it, because that’s all that appears to be on offer. Your careful ordering never came into play, because the attacker controls what reaches the server.

The fix is not reordering. The fix is deletion: you cannot be downgraded to a protocol version or cipher your server flatly refuses to speak. Set a minimum protocol version of TLS 1.2 (ideally 1.3) and remove every non-AEAD, non-ECDHE, and export suite from what the server will accept at all. With TLS 1.0/1.1 disabled and weak suites gone, there is no weak option left on the menu for the attacker to force. (TLS 1.3 also binds the entire handshake transcript into the Finished MAC, so any tampering with the offered suites is detected — but “don’t offer it” remains the durable control.)

Claim about the connectionWhat it actually provesWhat it does NOT prove
Valid cert / green padlockChannel encrypted + server authenticated nowThat past traffic survives a key theft
Strong suites listed firstWinner among honest, mutual suitesResistance to an active downgrade
ECDHE-only suites enforcedForward secrecy — past sessions safeThat the first hop was ever encrypted
301 redirect http → httpsHonest clients end up on HTTPSProtection against active SSL stripping

SSL stripping: the gap no cipher can close

Every property so far protects bytes that are already inside a TLS session. None of them protects the moment before the session exists. When a user types example.com, the browser’s first request often goes out as plain http://. A stripping man-in-the-middle intercepts that plaintext request, talks HTTPS to your server on the victim’s behalf, and serves them plain HTTP — the user never sees a padlock, and every byte flows in cleartext to the attacker.

The instinct “we issue a 301 redirect from http:// to https:// on every request” does not fix this. The redirect only fires if the attacker lets the plaintext request reach your server. An active stripping MITM intercepts that first http:// request before it ever arrives, never follows your redirect, and simply proxies plain HTTP to the victim. A server-side redirect cannot protect a request that never reaches the server.

The real control is HSTS (HTTP Strict Transport Security, RFC 6797). The server sends a Strict-Transport-Security header, and the browser remembers: for this domain, never send plaintext again — upgrade http:// to https:// before the request leaves the browser. Now there is no plaintext first hop to intercept. The remaining gap is the very first visit before any HSTS header was seen (trust-on-first-use); the preload list closes it by shipping the HSTS policy inside the browser itself, so the upgrade happens even on a cold first request. This is why hardening ciphers and protocols is necessary but not sufficient: stripping happens outside TLS, and only HSTS moves the defense into the browser where the plaintext hop lives.

Why this works

Why isn’t a redirect enough, concretely? Picture the victim on coffee-shop Wi-Fi controlled by the attacker. The victim’s browser sends GET http://bank.example/. The attacker’s box answers that request itself — it does not relay it to the bank — and meanwhile opens its own clean HTTPS session to the real bank. To the victim it’s an ordinary (plaintext) site; to the bank it’s a normal HTTPS client. The bank’s “301 → https” is never seen by the victim because the victim’s request never reached the bank. With HSTS already known for bank.example, the browser refuses to emit that http:// request at all and goes straight to HTTPS, removing the only plaintext message the attacker had to work with.

How a senior hardens a TLS endpoint

Put the four properties together and the playbook is mechanical — and the senior move is to adopt a named, standardized profile (Mozilla’s Server Side TLS recommendations) rather than hand-pick ciphers, because a hand-tuned list rots and reintroduces weak options. Versions: minimum TLS 1.2, keep 1.3, delete SSL 3.0 / TLS 1.0 / 1.1 — this closes version downgrade by deletion. Suites: ECDHE key exchange only, AEAD ciphers (AES-GCM, ChaCha20-Poly1305), no RSA key transport, no CBC — this gives forward secrecy and removes export/POODLE targets. Stripping: Strict-Transport-Security with a long max-age, includeSubDomains, then preload, plus a 301 from http to https. Operational hygiene: serve the full certificate chain (the leaf alone causes the “works in Chrome, fails in curl” bug because some clients can’t build the trust path), and enable OCSP stapling so revocation status travels with the handshake. Verify from the wire, not the file: run SSL Labs or testssl.sh against the live endpoint, because a deploy can silently keep an old config the file doesn’t show. The recurring discipline: TLS posture is something you test on the live endpoint continuously, not something you read off the intended config once.

Pick the best fit

A pentest report says your public site is vulnerable to a protocol downgrade because TLS 1.0 and an export cipher are still enabled. An engineer proposes: keep every version and suite enabled 'for compatibility' but move the strong ECDHE-AEAD suites to the top of the server's preference order. What's the correct call?

Quiz

A team confirms their site shows a valid certificate and a green padlock for every user. Why is that not enough to conclude recorded traffic is safe if the server's private key is later stolen?

Quiz

Why does a 301 redirect from http:// to https:// fail to stop an active SSL stripping attacker, where HSTS succeeds?

Order the steps

Order the steps of a TLS 1.3 handshake that establishes a forward-secret session:

  1. 1 Client sends ClientHello with supported versions, cipher suites, and an ephemeral key share
  2. 2 Server replies with its certificate and its own ephemeral key share
  3. 3 Server signs the handshake transcript with its long-term key to prove identity
  4. 4 Both sides derive the session key from the two ephemeral shares
  5. 5 Ephemeral keys are discarded; AEAD-encrypted application data flows
Recall before you leave
  1. 01
    Explain forward secrecy: what is the concrete difference between RSA key transport and ECDHE when an attacker steals the server's long-term private key after recording months of traffic?
  2. 02
    Why does reordering cipher suites fail to stop a downgrade attack, and why does a 301 redirect fail to stop SSL stripping — and what actually fixes each?
Recap

A TLS handshake does three things at once — authenticates the server, establishes an encrypted session, and provides integrity — and the green padlock only certifies that all three held at handshake time. It says nothing about three failure modes that a senior must reason about separately. First, forward secrecy: with RSA key transport a stolen long-term key decrypts all previously recorded sessions (“harvest now, decrypt later”); with ECDHE the session secret comes from discarded ephemeral keys, so a stolen key can’t touch the past. TLS 1.3 mandates this; on 1.2 you must restrict suites to ECDHE. Second, downgrade: an active MITM tampers with the ClientHello to force a weak version or export suite, so server cipher ordering is irrelevant — the fix is deleting weak versions and suites, not reordering them. Third, stripping: the plaintext first hop lives outside TLS, so a 301 redirect can’t protect a request the attacker intercepts before it arrives — only HSTS (ideally preloaded) moves the upgrade into the browser. The hardening playbook is mechanical: min TLS 1.2, ECDHE-AEAD only, HSTS + preload, full chain + OCSP stapling — adopt a named profile (Mozilla) and verify it on the live wire with SSL Labs / testssl.sh, because the config file can lie. So when someone says “we have HTTPS, we’re secure,” the senior questions are: is every suite ECDHE, is there a weak version still on the menu, and is the very first hop protected by HSTS rather than a redirect?

Practice

Start at the top. Tasks go easiest → hardest: recall a fact, apply it to a case, then a senior-level stretch. Open one, attempt it, then reveal.

recallapplystretch0 of 6 done
Connected lessons

Something unclear?

Ask a question about this lesson. Questions are anonymous and go straight to the author to make the lesson better.

shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.