Skip to content

Selective HTTP response compression by content type #609

Description

@NiccoMlt

Summary

BREACH needs three conditions on the same response: HTTP compression, attacker-controlled input reflected in the body, and a secret in the body (CSRF tokens, session data). Dynamic HTML and API responses can meet all three; static assets (text/css, application/javascript, image/svg+xml, fonts, …) are identical for every user and safe to compress.

Response compression is currently an all-or-nothing global switch: response.compression.threshold compresses every eligible response above the threshold (default 0 = everything), regardless of content type. The only way to mitigate compression-based side-channel attacks like BREACH is to disable compression entirely (-1), paying the full bandwidth cost.

Proposal

Add a MIME allowlist for response compression, e.g. a global response.compression.mime.types and/or a per-listener listener.<i>.compressionmimetypes, so that only listed content types are compressed. A sane default allowlist (static text assets, no text/html/application/json) could be applied on TLS listeners.

Implementation notes

Reactor Netty's compress(int) fixes the compression rule at listener build time. Per-response decisions (where Content-Type is known) require the compress(BiPredicate<HttpServerRequest, HttpServerResponse>) variant, evaluated at response write time. The two variants compose: compress(int) sets minCompressionSize, compress(BiPredicate) sets compressPredicate, and HttpTrafficHandler evaluates both (verified against Reactor Netty 1.2.6 docs and source).

If a per-listener property is introduced, consider aligning response.compression.threshold with a matching listener.<i>.compressionthreshold (global + listener-specific overrides, as already done for other settings).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions