The TLS protocol is designed to provide three essential services to all applications running above it: encryption, authentication and data integrity. The server creates a session for each TLS connection. Creating a session requires additional data, such as digital certificates and encryption keys, to be exchanged before any actual web data. The process of establishing a TLS session is called the handshake negotiation.
TLS Handshake Negotiation
Before the client and the server can begin exchanging application data over TLS, the encrypted tunnel must be negotiated: the client and the server must agree on the version of the TLS protocol, choose the encryption protocol and verify certificates if necessary. Unfortunately, each of these steps requires new packet roundtrips between the client and the server, which adds startup latency to all TLS connections.
New TLS connections require two roundtrips for a "full handshake". However, in practice, optimized deployments can speed up the process and deliver a consistent one roundtrip TLS handshake. Such optimized deployment is used when the client has previously communicated with the server. In this case an "abbreviated handshake" can be used, which requires one roundtrip and also allows the client and server to reduce the CPU overhead by reusing the previously negotiated parameters for the secure session. This technique is called TLS Session Resumption.
TLS Session Resumption
The extra latency and computational costs of the full TLS handshake impose a serious performance penalty on all applications that require secure communication. To help mitigate some of the costs, TLS Session Resumption provides a mechanism to resume or share the same negotiated secret key data between multiple connections. Session resumption is an important optimization deployment. The abbreviated handshake eliminates a full roundtrip of latency and significantly reduces computational costs for both sides. TLS Session Resumption can be implemented with session identifiers and session tickets mechanisms, while TLS 1.3 uses pre-shared keys (PSK) mechanism.
In this mechanism, the server assigns a random session ID during the initial handshake with the browser (client). Client and server store this session ID along with the session keys and connection states. To resume a session, the client sends the stored session ID with the first protocol message (ClientHello) to the server. If the server recognizes the connection and is willing to resume the session, it replies with the same session ID to re-establish the respective session. This allows a secure connection to be established quickly and with no loss of security, since we are reusing the previously negotiated session data.
However, one of the practical limitations of the Session Identifiers mechanism is the requirement for the server to create and maintain a session cache for every client. This results in several problems on the server, which may see tens of thousands or even millions of unique connections every day: consumed memory for every open TLS connection, a requirement for a session ID cache and eviction policies, and deployment challenges for popular sites with many servers, which should, ideally, use a shared TLS session cache for best performance. Hence, for any multi-server deployment, session identifiers will require some careful thinking and systems architecture to ensure a well operating session cache.
To address this concern for server-side deployment of TLS session caches, the "Session Ticket" (RFC 5077) replacement mechanism was introduced, which removes the requirement for the server to keep per-client session state. Instead, if the client indicates that it supports session tickets, the server can include a session ticket record, which includes all of the negotiated session data encrypted with a secret key known only by the server.
This session ticket is then stored by the client and can be included in the handshake message of a subsequent session. Thus, all session data is stored only on the client, but the ticket is still safe because it is encrypted with a key known only by the server.
The session ticket mechanism is referred to as stateless resumption mechanism. The main improvement of stateless resumption is the removal of the server-side session cache, which simplifies deployment by requiring that the client provide the session ticket on every new connection to the server until the ticket has expired.
Pre-Shared Keys (PSK)
The draft of TLS 1.3 replaces session IDs and session tickets with the concept of session resumption via pre-shared keys (PSK). After the initial handshake, the server sends a PSK identity to the client. The content of the PSK identity depends on the server and may contain a database lookup key or a self-encrypted and self-authenticated ticket. The client stores this PSK identity along with its own session keys.
In a subsequent handshake, the client provides this PSK identity within the ClientHello message to the server. Depending on the content of the PSK identity, the server decrypts the ticket and uses the contained session keys and connection states to resume the session, or the server uses the contained lookup key to find the session keys and connection states in its own database.
Unfortunately, in most cases security and utility are inversely proportional. On December 18, 2018 security researchers from the University of Hamburg published a paper describing a new method that web sites could use to track browser users’ history. Their technique exploits the session resumption feature implemented in the TLS protocol.
A session lasts for a predetermined period of time, from a few minutes up to several hours. If the browser revisits a server within the session window, the ongoing TLS session can resume via a single resumption request, instead of a full handshake negotiation.
In this respect, a TLS session resumption, being uniquely tied to a specific browser, can be used to track users in the same way cookies might. Essentially, when a browser resumes a session, the web site can correlate the connection with the one that originally created the session, even if the user visits from a different network (i.e. different IP address) or with different privacy settings (e.g. user-agent).
Using the above method, each individual user can be tracked for (at most) several hours, based on the length of the negotiated session window. However, a web site can renew a session for another period of time on each session resumption, resetting the session window and effectively extending the session’s lifetime indefinitely. The paper calls this technique a prolongation attack.
The researchers have demonstrated that this technique can be used to permanently track 65% of the users in their dataset, because those users tend to visit tracking web sites more often than sessions expire. The researchers conclude:
Our results indicate that with the standard setting of the session resumption lifetime in many current browsers, the average user can be tracked for up to eight days.
Fixing this hypothetical weakness won’t be easy. Browser makers could set lower lifetimes for session identifiers or even dispense with them completely, but that might impact performance. Another solution might be to allow session resumption for first-party domains but not third-parties. However, this would inevitably be seen as a hit on traffic and latency given that most websites make numerous third-party HTTPS TLS connections.