BREACH is a vulnerability that is present when several conditions are met:
- HTTP compression is used,
- A part of the input is reflected,
- A static secret is present in the HTTP body of the response,
- The attacker can read the size of the encrypted response,
- The attacker can forge requests to the site under attack.
Each of these conditions pose no threat in themselves, but combined they lead to a vulnerability. This is partly the reason that there is no clear-cut solution to this vulnerability: simply upgrading Apache or OpenSSL is not enough. Disabling gzip compression for everything does not make much sense. Reflecting user input is totally fine most of the time. There is not really a simple solution, but there has been made some progress in the last years to mitigate BREACH.
One of the best solutions is the same-site cookie flag. This makes cookies no longer work on cross-origin requests, which solves CSRF-attacks and thus also BREACH. Somebody is working on a specification and it is already implemented in Chrome, Firefox, and Edge on Windows 10. Chrome is even working on making all cookies SameSite by default, thus solving BREACH and all other CSRF-like attacks in Chrome.
There are also several projects that randomize the response length. Some modules put a random HTML comment in each response, which is a total hack. Padding support has been formalized in TLS 1.3, but it will take some time before that is implemented in servers.
Some frameworks have also taken steps to mitigate BREACH attacks, particularly to prevent guessing of the CSRF token. Django randomizes the CSRF token on each request, so that it can not be guessed over multiple requests. This is relatively new, released this year in Django 1.10.