The final swipe in the great whack-a-mole game of web encryption may finally have been swung.
It hasn’t struck home yet but the backswing looks good and the aim is true. Behind the bat is Cloudflare – who else? – and its target is an obscure but widely used technology called SNI (Server Name Indication).
SNI is a bit of unencrypted data that contains the name of the website you’re visiting.
It’s sent by the browser when you view websites securely and, ironically, this unencrypted tidbit of data has played a crucial part in making encryption the exception rather than the rule on the web.
SNI is a trade-off – it opens a small privacy hole at the expense of closing a much bigger one – and as such it has always been a job half done. Everyone knew that sooner or later it would need fixing but nobody was quite sure how to.
After considerable head scratching, Cloudflare is about to test its answer to the SNI conundrum, Encrypted SNI, with partners Mozilla.
So let’s look at what SNI does, why fixing it was hard and what Cloudflare is up to.
When you visit a website using an encrypted HTTPS connection, your computer asks the server hosting the website for its digital certificate. It compares the name in the certificate with the name of the site it wants to talk to, to ensure they’re one and the same. If they match, an encrypted tunnel is created between the two computers and HTTP messages can be sent and received over that tunnel.
However, there’s a Catch-22 if, as happens frequently, you want to visit a website on a server that’s hosting lots of different websites with different certificates.
Your computer has to tell the server which website it wants a certificate for, so it can create an encrypted tunnel, but it tells the server which website it wants using HTTP, and it can’t send HTTP messages until it’s created an encrypted tunnel…
Enter SNI to break the deadlock.
SNI allows a web browser to send the name of the website it wants to connect to up front, before the encrypted tunnel is formed, so the server knows which certificate to send.
Because it’s sent in plain text, before the encrypted tunnel is created, your SNI data can be read by anyone who can intercept your browsing traffic, such as an ISP or rogue Wi-Fi access point, revealing the websites you’re visiting.
Only a few short years ago the web was largely unencrypted and the entire contents of your HTTP messages could be pored over and modified by interlopers. In that context, the SNI leak was a small price to pay for the huge privacy and security boost it enabled by making HTTPS on shared hosts easier.
Now that encrypted HTTP is the norm, attention is switching to SNI and DNS – two plain text protocols that can be intercepted to see what websites you’re visiting.
Efforts to fix DNS have attracted far more attention than SNI (probably because it’s more widely used and easier to fix), and multiple solutions have emerged such as DoH (DNS over HTTPS) and DNS over TLS, DNSCrypt and the interesting and esoteric Oblivious DNS.
You can see how HTTPS, DNS encryption like DoH and ESNI combine to hide different parts of your browsing data in the table below:
|via HTTP||via DNS||via SNI|
|DNS + HTTP||✘||✘||✘||✘|| |
|DNS + HTTPS + SNI||✓||✓||✓||✘||✘|
|DoH + HTTPS + SNI||✓||✓||✓||✓||✘|
|DoH + HTTPS + ESNI||✓||✓||✓||✓||✓|
How ESNI works
The process of negotiating an encrypted tunnel between your browser and a web server is called the “handshake”. It involves sending plaintext SNI data to tell the server which certificate you want, checking that you’re talking to that server, agreeing which ciphers to use and exchanging encryption keys.
Fixing SNI is hard is because the SNI data you send needs to be decrypted by the server before it can perform the handshake that tells it how to decrypt your messages. Or, as Cloudflare itself put it in its detailed explanation on the subject:
If the chicken must come before the egg, where do you put the chicken?
The answer is, you put it in DNS (Domain Name System), the global internet address book used to associate human-readable names like
example.org with IP addresses like
Computers find and talk to one another using IP addresses, so the first thing your computer does when you tell it to visit a website is quickly lookup up the IP address using DNS.
Cloudflare want website owners to create a pair of cryptographic keys – one public, one private – and publish the public key in a DNS entry (where web browsers can pick it up before visiting a website), alongside their IP address.
The public key can be used by anyone to derive a symmetric encryption key that only the owner of the secret, private key (the website owner) can unlock.
Since only the client, and the server it’s connecting to, can derive the encryption key, the encrypted SNI cannot be decrypted and accessed by third parties.
When it wants to connect to a website using ESNI your browser will generate its own, ephemeral, public and private key pair that will be used once and discarded, to prevent replay attacks.
While this may seem overly complicated, this ensures that the encryption key is cryptographically tied to the specific TLS session it was generated for, and cannot be reused across multiple connections.
The browser uses its ephemeral private key and the server’s public key to derive an encryption key, encrypts the SNI data and sends it to the website along with the public portion of its ephemeral key.
The server then uses its private key and the browser’s public key to derive the encryption key that can decrypt the SNI data, and the handshake for the encrypted HTTP session can begin.
Although it’s Cloudflare’s baby, the company is trying to turn ESNI into an open standard via the IETF (Internet Engineering Task Force). The feature is already available for anyone using Cloudflare name servers but no browsers support it yet, although it’s expected to be a feature of Firefox’s bleeding edge nightly builds imminently.