Recently WhiteSource security scanner started reporting WS-2016-7107 against Spring-based applications. This is an old issue in Spring Security that was reported in 2016. Unfortunately, at the moment of writing it, the issue has not been fixed yet. But there is a pull request that should address it. The problem is that CSRF tokens generated by Spring Security are vulnerable to the BREACH attack. The attack is even older — it was published in 2013. The BREACH attack is similar to the CRIME attack but BREACH doesn’t need TLS compression.
(you can also read it on Medium)
There are several conditions for a successful attack:
- The attacker should be able to inject partially chosen plaintext into the victim’s requests (that is usually called chosen-plaintext attack model).
- The attacker should be able to observe the encrypted traffic from the victim.
- HTTP compression should be enabled.
TLS configuration doesn’t matter. In the case of a Spring-based application, a successful attack allows the attacker to recover the victim’s CSRF tokens. That’s what WS-2016-7107 is about.
The issue seems to get quite a lot of attention because WhiteSource reports it against almost all applications that use Spring Framework. Look at the number of linked WhiteSource reports in the original issue on GitHub. And that’s only projects on GitHub that use WhiteSource. What makes it worse is that the issue is still open. Therefore, it is not possible to fix this issue in an application just by bumping the version of Spring Security. Furthermore, if the proposed fix is accepted, it will be likely released only in the next major update of Spring Security because the fix updates the public API.
Looks like the most reliable way to eliminate the risk of the BREACH attack completely is to make sure that HTTP compression is disabled. The good news is that HTTP compression is disabled by default in the latest version of Spring Boot. Unless an application sets the property
true, the BREACH attack should not be possible. To be sure, it would be better to test whether HTTP compression is enabled on not:
GET /path/to/something HTTP/1.1 Host: test.server.com Accept-Encoding: gzip, deflate
Here is how you can do it with
curl -v -H "Accept-Encoding: gzip, deflate" https://test.server.com/path/to/something
If the server returns “Content-Encoding” header with a list of supported compression methods, then HTTP compression is on. Wikipedia has an example of such a response. Otherwise, HTTP compression is off.
If HTTP compression has to be on, there may be another option. The application can implement a custom
CsrfTokenRepository that applies the unreleased fix for Spring Security. I have not tested this option though.
Let’s hope the issue will be fixed soon in Spring Security.