SuperCooKey – A SuperCookie Built Into TLS 1.2 and 1.3
In doing my research around the impact of TLS 1.3 for Private Internet Access, I came across some peculiar items in the new standards.
TLS 1.3 represents a relatively large shift in cryptography, so much so that it was debated whether it should be called TLS 2.0 rather than 1.3. It throws away a lot of old cryptography in favor of newer algorithms that adhere to perfect forward secrecy. That is, by never reusing security keys throughout multiple sessions, you gain privacy and security benefits.
The Benefits of Perfect Forward Secrecy are Two-Fold:
Security: Cryptography using ephemeral (one-time) keys is harder to break, because an attacker has to break each session to fully decrypt a user. With static (unchanging) keys, you are reusing the same keys for every session, which means that if one session is broken through a security vulnerability or bad cryptography, all of the previous sessions are also broken because they were using the same keys.
Privacy: If you’re not signing in to a website, and not outed through other browser settings, an ephemeral session should look like a new visit every time you go to a website, because you’re using a new secure session on each visit.
One of the Flagship Features of TLS 1.3 Abandons the Privacy Benefit:
TLS 1.3 has a heavily touted feature called 0-RTT that has been paraded by CloudFlare as a huge speed benefit to users because it allows sessions to be resumed quickly from previous visits. This immediately raised an eyebrow for me because this means that full negotiation is not taking place.
After more research, I’ve discovered that 0-RTT does skip renegotiation steps that involve generating new keys.
As authentication and establishment of cryptographic keys in 0-RTT without prior knowledge is impossible, 0-RTT key-exchange protocols must leverage keying material obtained in some prior communication to establish 0-RTT keys.
This means that every time 0-RTT is used, the server knows that you’ve been to the site before, and it knows all associated IPs and sign-in credentials attached to that particular key.
Hand Waving by the Security Community Ignores Serious Privacy Risks:
“That’s just surveillance with extra steps!”
The 0-RTT design focuses on keeping “forward secrecy” by changing the keys between each session in a predictable way (hashing / salting / raising the key by an exponent / etc) to generate a new key. This (sort of) fixes the security problems with 0-RTT, but this has multiple serious privacy problems that are not forward secret.
1. The client has to store this key for future use, instead of destroying it. This opens up these stored session keys to the attack surface of the entire web browser for the time period that the session information is stored.
2. The server has to store this key for future use, instead of destroying it. This means that the TLS 1.3 0-RTT process is fundamentally flawed, as it specifically requires the server to delete information with no verifiable method of doing so. This means that a malicious server can easily follow these keys without deleting them, and associate the 0-RTT session with all previous visits from that original first key. A design that requires internet users to “trust” that no one will do this is a fundamentally broken design.
Here is further scholarly research on how damaging these security practices can be:
An excerpt from section 7 of the paper:
In particular, the “shape” of the vulnerability windows created by session tickets is ideally suited for exploitation by intelligence agencies for surveillance purposes.
The Use-Case That is Threatened by 0-RTT: Privacy Networks
This means that not only can websites track your sessions across all known IPs, but that large networks that you frequently hit (think Google Analytics, Google AMP, CloudFlare, Facebook, Twitter, JS libraries, Amazon Web Services, Microsoft Azure etc) can follow you all over the internet and link all of your activity across many sessions.
What This Looks Like – Identifying a VPN user using 0-RTT
For a real world example that demonstrates this issue, I visited a TLS 1.3 enabled site with a default build of the latest Firefox. I then closed the browser, signed on to a VPN service, and then visited the same website. While everything on the surface looks the same when you do this, and your IP address is functionally different, under the hood we have a problem. Here’s a WireShark of that second visit:
To be clear, this pre_shared_key identity is uniquely linked to you. Using privacy services with this feature enabled is like putting on a disguise to get into a bar you were kicked out of, and then handing the bouncer your photo ID.
The Problem is Worse in TLS 1.2
0-RTT is an “improvement” over a prior implementation of early_data that applies similar principles. 0-RTT is better in that it doesn’t continuously re-use the same static key, and at least changes it from session to session, making it harder for a man in middle to learn the shared secret. However, to gain the performance edge in 0-RTT, session resumption has to be carried out without replay protection.
In essence, the TLS 1.2 version of session resumption is less safe because the standard has no defined mechanism for changing keys like TLS 1.3s 0-RTT, and both the TLS 1.2 and TLS 1.3 versions of session resumption ignore the principal of ephemeral data and allow services to track users with very high accuracy.
Session IDs, Session Tickets, and 0-RTT are enabled by default in “Private Mode” on Firefox
This means that even while in private mode, and with privacy extensions installed in Firefox, this problem persists and can out you.
Mitigation in Firefox
To mitigate this, you need to be able to disable both TLS 1.2 and TLS 1.3 session resumption. There are four settings related to this scenario that we have to change to fully address the problem.
security.ssl.disable_session_identifiers (hidden feature) security.ssl.enable_false_start security.tls.enable_0rtt_data privacy.firstparty.isolate
This is the 0-RTT feature itself. Disabling this feature disables the ability for the server and browser to negotiate a 0-RTT connection using related keys and no replay protection.
To disable 0-RTT: Type about:config into your navigation bar in Firefox. In the screen that pops up, enter security.tls.enable_0rtt_data into the search bar, and make sure that the setting is set to FALSE.
Next, we have to disable the TLS 1.2 session resumption mechanisms. This prevents Firefox from being able negotiate session resumption using static session IDs or session tickets.
security.ssl.disable_session_identifiers (HIDDEN FEATURE)
To disable session identifiers: Type about:config into your navigation bar in Firefox, in the screen that pops up, you must right click on a blank area of the page and select new -> boolean.
In the window that pops up, we have to enter the exact name of the hidden feature: security.ssl.disable_session_identifiers and hit OK.
Then we have to search for the feature that we added and make sure that it is set to TRUE.
The next two features help to isolate the problem, and explicitly prevent 3rd party services from tracking you by using session IDs, session tickets, and related keys.
This feature prevents the browser from making requests to sites outside of the primary domain from the site. This prevents large ubiquitous services from following your keys around the web like a supercookie.
To enable first party isolation: Type about:config into your navigation bar in Firefox. In the screen that pops up, enter privacy.firstparty.isolate into the search bar, and make sure that the setting is set to TRUE. (This setting can break websites that rely heavily on 3rd party libraries and scripts.)
Lastly, we have to disable False Start. This is because it does not allow the client to fully complete its handshake before starting the actual session. There is more info here from the IETF: https://tools.ietf.org/html/rfc7918#section-4 (See section 5. Security Considerations)
To disable TLS false start: Type about:config into your navigation bar in Firefox. In the screen that pops up, enter security.ssl.enable_false_start into the search bar, and make sure that the setting is set to FALSE.
The combination of these 4 changes restricts the browser to only using real ephemeral cryptography as the TLS 1.3 specification intends throughout the entirety of the rest of the standards. 0-RTT, Session Tickets, Session IDs, and other shortcuts undermine the progress that internet standards are making toward ubiquitous strong security and privacy on the web. In this case, a few milliseconds while loading a web page are saved by sacrificing fundamental privacy and security gains made over the last twelve years.
I am currently researching mitigations for this problem in Chrome, but full mitigation does not seem possible at this time. Contact me if you believe you know how to fully disable session IDs, session tickets, and 0-RTT in Chrome/Chromium or other browsers, and I will edit in the mitigation here.
Stay safe and private out there!