TL;DR
Adding a random ‘salt’ to compressed web pages can help mitigate the BREACH attack, but it’s not a complete solution. It makes exploitation harder, but determined attackers can still succeed. Proper HTTP/2 header compression (like QPACK) is much more effective.
What is BREACH?
BREACH (Browser Reconnaissance and Exfiltration via Adaptive Compression of Hypertext) exploits the way web servers compress data sent to browsers, specifically when using gzip or similar compression algorithms. It allows an attacker to steal sensitive information like cookies by injecting malicious content into a compressed HTTP response and observing how the server responds.
How Salting Works
Salting involves adding random data (the ‘salt’) to the content before it’s compressed. This changes the compression patterns, making it harder for an attacker to predict which parts of the page are sensitive information and therefore easier to steal. The idea is to disrupt the statistical analysis attackers rely on.
Steps to Implement Salting
- Generate a Random Salt: Create a unique, random string for each request or session. This salt should be long enough (at least 16 bytes) to provide sufficient randomness.
- Prepend the Salt: Add this salt to the beginning of the content before compression. For example:
salt = "random_string_"; content_with_salt = salt + original_content; compressed_data = compress(content_with_salt); - Send Compressed Data: Send the compressed data to the browser as usual.
- Remove Salt on Browser Side: The browser needs to remove the salt before rendering the page. This requires changes to your JavaScript code.
var received_data = decompress(compressed_data); var salt_length = 12; // Length of the salt used var content = received_data.substring(salt_length);
Why Salting Isn’t a Perfect Fix
- Increased Payload Size: Adding a salt increases the size of the data sent, potentially slowing down page load times.
- Complexity: Requires changes to both server-side and client-side code.
- Still Vulnerable: A determined attacker can still attempt to bypass salting by carefully crafting their injection attacks and analysing compression patterns over multiple requests. The salt needs to be truly random and unpredictable for each request.
- JavaScript Dependency: Relies on JavaScript being enabled in the browser, which isn’t always guaranteed.
Better Solutions
- HTTP/2 Header Compression (QPACK): QPACK is designed to be resistant to BREACH-style attacks. It avoids the weaknesses that gzip compression exploits. This is the preferred solution if you can use HTTP/2.
- Disable Compression for Sensitive Data: If possible, avoid compressing sensitive data like cookies or personally identifiable information (PII).
- Use Secure Cookies: Setting the
HttpOnlyandSecureflags on cookies helps protect them from client-side attacks.
Conclusion
Salting can offer a small degree of protection against BREACH, but it’s not a robust solution. Prioritise upgrading to HTTP/2 with QPACK or disabling compression for sensitive data whenever possible. Consider salting as an additional layer of defence, not a replacement for more effective security measures.