Network Privacy

TLS Session Resumption: The Cookie Built Into the Handshake

July 10, 2026 7 min read Haven Team

Every TLS connection starts with a handshake that costs a round trip and some public-key cryptography. Resumption exists to skip that cost when you reconnect: the server hands your browser a ticket, and your browser presents the ticket on its next visit. A token issued by a server, stored by your client, and presented on return visits is also a working definition of a cookie, and it took researchers a while to treat it like one.


Session resumption is one of the oldest performance features in TLS, and for most of its life nobody thought of it as a privacy surface. It lives below the layer where tracking discussions usually happen, in the handshake itself, before a single HTTP header is sent. That location is exactly what makes it interesting: identifiers at the TLS layer survive the cleanups users perform at the browser layer.

How Resumption Works

TLS has shipped three mechanisms for skipping the full handshake, and all three share the same basic move: keep enough cryptographic state from the first connection to shortcut the second.

Mechanism Where the state lives Versions
Session IDs Server keeps a session cache; client presents a short ID to look it up TLS 1.2 and earlier
Session tickets (RFC 5077) Server state is encrypted into a ticket the client stores, so the server stays stateless TLS 1.2 and earlier
PSK resumption Server sends NewSessionTicket after the handshake; client redeems it as a pre-shared key, optionally with 0-RTT data TLS 1.3

The performance win is real, especially on mobile networks where round trips are expensive, and in TLS 1.3 resumption also enables 0-RTT: the client can send application data in its very first packet, encrypted under the resumed key, before the server has said anything at all.

The Tracking Property

Look at the ticket from the server's perspective. It issued a unique blob to one specific client, and some time later a connection arrives presenting that blob. The server now knows this is the same client, regardless of whether the IP address changed, whether cookies were cleared, and in some configurations whether the browser was in private mode when the ticket was issued. No script needs to run. The linkage happens in the handshake, before the page exists.

In 2018, researchers at the University of Hamburg (Sy, Burkert, Federrath, and Fischer) published a paper titled "Tracking Users across the Web via TLS Session Resumption" that measured how far this stretches in practice. Two findings mattered. First, real-world ticket lifetimes were long: TLS 1.3 permits tickets to live up to seven days, and the browsers of the day held resumption state far longer than the few minutes privacy would suggest. Second, and worse, the lifetime is renewable. A server can issue a fresh ticket on every resumed connection, so for any site you visit at least once within each ticket lifetime, the chain never breaks. The paper called this prolongation, and it turns a seven-day identifier into an indefinite one for any regularly visited site.

The third-party version was the alarming one. A tracker embedded on many sites gets a resumption ticket from your browser on each of them, and if that state is shared across contexts, the tracker links your visits across the web at the transport layer, invisible to every cookie control and content blocker you run.

Aside: when tickets leak more than identity

Session ticket handling has produced at least one memorable vulnerability of its own. Ticketbleed (CVE-2016-9244), found by Filippo Valsorda in F5 load balancers, leaked up to 31 bytes of server memory per handshake because of a session ID length mismatch during resumption. Small pieces of handshake plumbing carry real attack surface.

What Browsers Changed

The third-party linkage is largely closed now, through the same mechanism that closed cache-based tracking: network state partitioning. Firefox began partitioning TLS session state along with the rest of its network state in Firefox 85 in early 2021, and Chrome's network partitioning does the same. TLS resumption state is keyed by the top-level site you are visiting, so the ticket a tracker gets while embedded on site A is never presented while it is embedded on site B. The tracker sees two unrelated first-time visitors.

First-party linkage remains, by design: a site you visit directly can still recognize your returning browser at the TLS layer for as long as the ticket chain stays alive. Browsers bound this with lifetime caps, by dropping resumption state when you clear site data, and by isolating private windows, which start with no resumption state and discard what they accumulate. Tor Browser goes furthest and isolates all network state per first-party site as a matter of design.

The Forward Secrecy Cost

Tracking is not the only privacy property resumption bends. Session tickets are encrypted under a key the server holds, usually called a session ticket encryption key or STEK. In TLS 1.2, that ticket contains the session's master secret. An attacker who obtains the STEK can decrypt recorded traffic for every session whose state was wrapped in it, which quietly converts a forward-secret connection into one whose secrecy depends on a long-lived key sitting on the server, or replicated across a CDN's entire fleet. TLS engineers have been pointing at this gap since 2013; the operational fix is rotating STEKs frequently and never writing them to disk.

TLS 1.3 improved the defaults. Resumption keys are derived through the key schedule rather than being the master secret in a box, and servers can require a fresh Diffie-Hellman exchange alongside the ticket (the psk_dhe_ke mode), which restores forward secrecy for resumed sessions. The remaining sharp edge is 0-RTT: early data can be replayed by an attacker who captures it, so it is safe only for requests that are harmless to repeat, which is why well-run deployments restrict it to idempotent requests or disable it.

What This Means in Practice

If you run servers: rotate ticket keys on a schedule measured in hours, keep them out of persistent storage, keep ticket lifetimes short, require DHE on resumption, and treat 0-RTT as off until someone demonstrates the replay analysis for your endpoints. If you use a browser: the partitioning work of 2020 and 2021 already removed the cross-site version of this tracker, keeping the browser current is what maintains that, and private windows plus clearing site data handle the first-party remainder.

The broader lesson generalizes past TLS. Any state a protocol stores on the client to save a round trip is a pseudonymous identifier, whatever it was named for. DNS caches, HSTS pins, prefetched resources, and handshake fingerprints have all been bent into tracking at some point. The privacy work of the past few years was mostly not inventing new cryptography; it was going through the plumbing, finding every one of these, and partitioning it.

Try Haven free for 15 days

Encrypted email and chat in one app. No credit card required.

Get Started →