I am writing full-stack server side software and I have been researching CRIME attacks and it's relation to SPDY header compression as I am implementing the server side codecs for it at the moment.

The conclusion seems to be that compression and encryption should not mix.

Having looked into both CRIME and BREACH. I am wondering if the following methods are viable to disable ALL types of "guess work" attacks in compressed and encrypted data streams (on the server side)

1) Rate-limiting - as suggested on BREACH's site. Any clients bombarding a server with over 100 request per second is bound to be malicious when pages on your sites only serves a maximum of X (single/low double digit) resources per request.

2) Dynamic data - both CRIME and BREACH (and their derivative) seems to rely on repeated probing and assumes the position of data does not change. What if both HTTP headers and body are shuffled per response by the server? Combined with small variable length random dummy data injected in both body and header? Can this effectively disable all such attacks with CRIME and BREACH's characteristics?

Thanks for your time.

EDIT 1: I should point out that I am specifically referring to data streams within the HTTP protocol (i.e. HTTP compression and SPDY header compression) and not SSL/TLS compression.

EDIT 2: The attack mitigation solution I am trying to achieve/suggest is on all possible "compression + encryption" info leak attacks, CRIME and BREACH may only be recent examples.

EDIT 3: The BREACH presentation seems to suggest variable length padding is not a valid mitigation. However it doesn't seem to consider the combination of a randomised message structure + randomised padding can create an (in theory) infinite combination of unreliable outputs thereby removing any correlation between the compressed and encrypted output length to the actual message meaning.

2 Answers 2


CRIME and BREACH are attacks on the client. Their setup is that some hostile code is running in the client with limited capabilities (i.e. it is Javascript in a Web page). The attacker also controls the external traffic of the victim: he can inspect it, but also block it. This limits what the server actually sees.

In both cases, the hostile Javascript will trigger several (many) requests aimed at the server for which the secret (the cookie value) is to be retrieved. The attacker only needs to see what goes out of the client; it is not absolutely needed that the request reaches the server. Indeed, HTTPS clients use HTTP: they routinely send several requests in a row over a single channel and don't mind that they don't receive a response immediately. This way, the hostile code makes the victim's browser send a lot of requests that the attackers see, but not the server.

Under these conditions, there is very little that the server can do to protect the client, except not letting it believe that the vulnerable protocol features (unprotected CBC, compression...) can be used at all. Rate limitations won't do much in this case.

Injecting some random padding is a possible defence, but it has to be done in the client, not in the server. There again, the server cannot do anything. A custom header, with random contents and occurring before the cookie in the header, would prevent BREACH. For CRIME, this is more complex; you need a custom header with a random length with a well-chosen distribution (it is not immediately obvious which distribution should be used). Of course, this extra padding implies more bytes to send, which may very well cancel the benefits of using compression in the first place.

  • Thanks for this detailed explaination, I have neglected to consider that requests does not necessarily reach the server on the client side. However, would you not say that the server is at risk of similar attacks? Specifically for BREACH where the actual content of the encrypted request/response is targeted. I believe BREACH is applicable to server applications.
    – user31523
    Commented Oct 3, 2013 at 12:39
  • Both BREACH and CRIME are chosen plaintext attacks. They need the attacker to choose part of a message which also contains a secret value that the attacker wants to recover. This does not map well to a Web context, where secrets are mostly client-side (the cookie). To apply to the server, there should be some sort of page which reflects data from the client request, and also contains a new cookie value to store; and this should work with requests that the client may send from hostile Javascript from another site (i.e. GET, not POST). That's rather restrictive.
    – Tom Leek
    Commented Oct 3, 2013 at 12:57
  • breachattack.com seems to suggest it is primarily a server side issue where the leak secret is the contents of the response body.
    – user31523
    Commented Oct 3, 2013 at 13:22
  • @TomLeek CSRF tokens are one example of a secret that's sent from the server to the client. Commented Oct 3, 2013 at 17:14
  • 1
    @JohnDeters "A" fix is to turn off compression: and for many, many web applications, it's a severe performance penalty. AES-encrypting secrets (i.e. your CSRF token) on a per-request basis is typically fairly straightforward, fairly quick and doesn't break the back button (or multiple tabs!). django-debreach has a good example of this in play.
    – elithrar
    Commented Nov 7, 2013 at 22:54

@Tom, It's an attack on TLS, so it's involves both the client and the server. Part of the exploit runs on the client, but the attack is on the server response bodies with BREACH. Headers are not compressed with HTTP compression. I think you have BREACH and CRIME confused in your 4th paragraph.

1) Rate limiting will slow the attack down, but wont stop it. This sort of detection will stop a fair amount of attacks, but I guess has been to difficult to implement.

2) Even if your padding is completely random, or distribution is offset, you can still take a certain number of requests and average them to obtain a result. This makes the attack more expensive but not impossible.

I wouldn't any of these unless you're okay with mitigation, not remediation.

Why not just put a random CSRF token on every request and build the framework around that, so an attacker never knows the what a valid request looks like so they can't force you to make it?

  • 1
    The problem with a random CSRF token per request is that it comes at a cost to usability (back-button) and that CSRF cannot be applied to GET (URL) requests.
    – user31523
    Commented Oct 4, 2013 at 4:56
  • One can use HMAC of real CSRF token and random salt combined. The client visible CSRF token is "<salt>:<HMAC of CSRF token + salt>". Just randomize the salt for every request and actual CSRF token looks random to attacker. Commented Jan 11, 2017 at 9:53

You must log in to answer this question.