Summary
Selective compression (by content type #609 and per action #610) reduces the BREACH surface by not compressing risky content. Two limits remain:
- where compression is deliberately kept on dynamic content (bandwidth/performance), the BREACH oracle stays open;
- the only available defense is "turn compression off", paying full bandwidth.
The literature offers a third, complementary mitigation: length hiding (Heal-the-BREACH). Appending a random-length padding to each response hides the ~1-byte size variations the attack measures on the encrypted channel.
This is a statistical mitigation, not a cryptographic fix: an attacker averaging enough samples can still succeed, but the attack becomes slow and extremely noisy (~10⁶ anomalous requests, trivial to detect/block with rate limiting or an IDS).
Two options from the literature, different trade-offs:
- gzip header padding (the paper's approach): inject a random-length fake filename in the optional
FNAME field of the gzip header (RFC 1952). DEFLATE stream and checksums untouched, decompressors ignore the field. Covers any compressed content type (JSON included), but requires replacing Reactor Netty's compress() handling with a custom compressor.
- Comment injection (as in nginx's length-hiding-filter module): append a random high-entropy comment (
<!--…--> for HTML/XML, /*…*/ for CSS/JS) to textual responses at write time. Much simpler and hot-reloadable, but limited to comment-friendly MIME types (no JSON) and touches the body (Content-Length fixup, HEAD/304 exclusions, backend-compressed responses, …).
Summary
Selective compression (by content type #609 and per action #610) reduces the BREACH surface by not compressing risky content. Two limits remain:
The literature offers a third, complementary mitigation: length hiding (Heal-the-BREACH). Appending a random-length padding to each response hides the ~1-byte size variations the attack measures on the encrypted channel.
This is a statistical mitigation, not a cryptographic fix: an attacker averaging enough samples can still succeed, but the attack becomes slow and extremely noisy (~10⁶ anomalous requests, trivial to detect/block with rate limiting or an IDS).
Two options from the literature, different trade-offs:
FNAMEfield of the gzip header (RFC 1952). DEFLATE stream and checksums untouched, decompressors ignore the field. Covers any compressed content type (JSON included), but requires replacing Reactor Netty'scompress()handling with a custom compressor.<!--…-->for HTML/XML,/*…*/for CSS/JS) to textual responses at write time. Much simpler and hot-reloadable, but limited to comment-friendly MIME types (no JSON) and touches the body (Content-Lengthfixup, HEAD/304 exclusions, backend-compressed responses, …).