Skip to Main Content

TLS is the primary stream encryption protocol used by technologies like HTTPS to prevent eavesdropping and other man-in-the-middle attacks. It is the most well-tested and dependable technology of its class, and is used for almost every scenario that requires encryption of streaming data.

 

However, there is one part of the TLS standard that isn't so well-tested: TLS supports protocol-level compression, which is intended to reduce the size of the data during transport in order to speed up delivery. This feature has never really been used in HTTPS scenarios, since the HTTP layer already supports compression in a more flexible manner, and web browsers never bothered to support TLS-level compression.

However, Google has recently changed that, in its "SPDY" initiative to make the Web "faster by default". Seeing that there is a large amount of compressible content that their HTTP servers haven't been configured to compress, Google decided that the solution is to enable compression on the TLS layer. They submitted changes to the Apache Web server and got recent versions of both Chrome and Firefox to support it.

Unfortunately, some security researchers have just discovered some very alarming issues with the way TLS does compression, which appears to render it fundamentally insecure.

The problem is that the compression method inherently leaks information about the plaintext content:

Normally, the values in the plaintext content have no discernible effect on the encrypted content if the length of the plaintext remains the same. In other words, there is no way to tell an encrypted "foofoo" apart from an encrypted "foobar". Both encrypted values would end up being the same length and would both be indistinguishable from random data.

However, compression changes this. "foofoo" is more compressible than "foobar", which means, after compression and encryption, the result of "foofoo" will be shorter than the result of "foobar", and a man in the middle can see that it's shorter. If an attacker can force the user's browser to send attacker-controlled form data to the HTTPS site (for example, by using some JavaScript code to make background requests) along with the user's cookie data, the attacker can test a variety of inputs to see how they affect the length of the compressed/encrypted stream, indicating whether the input compressed with the cookie data and thus matched the cookie data. This has the potential to reveal the contents of session cookies and other security-related HTTP headers. Although this is a type of brute force attack, it requires far far fewer trials than traditional password brute forces, since the attacker can reveal one character at a time (so, a 32-byte-long base-64 token can be revealed by an average of 1024 trials, rather than 3.1 * 10^57 trials with a traditional brute-force).

Note that the traditional method of compression (at the HTTP layer) doesn't have this problem, since HTTP-level compression typically only applies to the response body, not the headers. Also, HTTP-level compression uses separate gzip streams for each thing being compressed, which means it doesn't reveal any redundancy between separate compressed bodies (such as the form data and cookies). There might still be ways to exploit HTTP-level compression to leak some of the HTML response, but this would require a much more difficult scenario for the attacker to pull off.

In response to these discoveries, both Firefox and Chrome have released browser updates which disable support for TLS-level compression. Internet Explorer never supported it, and Opera only supported it in beta versions (from which it has also now been removed). Apple hasn't indicated whether Safari supports it.