Repository navigation
Conversation
Caddy 2.11.7 compresses text/event-stream responses. Each compressed stream keeps an encoder for the whole connection, which costs memory per subscriber, and compressing secrets alongside attacker-influenced data enables BREACH-style attacks.
|
Can I suggest giving some more information - metrics etc... - about what the actual cost is of compressing the SSE stream? I ask this because it is very much my intention to compress the stream, as it can result in immense bandwidth savings - it is a standard approach for SSE-based web frameworks like Datastar https://data-star.dev/guide/the_tao_of_datastar/#compression |
|
Here are the numbers. Since Caddy 2.11.7, each compressed SSE connection keeps its encoder for the whole lifetime of the stream. With Caddy's default settings, that's about 2.7 MiB per subscriber with zstd and about 1 MiB with gzip. 10,000 concurrent subscribers then need around 27 GiB of RAM for zstd alone. That persistent context is also what gives the high ratios mentioned in the Datastar guide: each event is compressed against the previous ones. It's also what makes BREACH more practical than on regular responses. Say a stream carries both a secret (for example a CSRF token in a rendered fragment) and content an attacker can influence (a chat message, a comment). An attacker who can observe the encrypted traffic can then publish guesses and read the size of each event, without making the victim send any request. So it depends on the app, and the sample |
|
Thanks for the information! Would definitely be useful to add such details to the docs. How much ram does brotli require, in comparison? By the way, the Sec-Fetch-Site header is a simple and viable replacement for CSRF tokens. Might mitigate some of that risk? |
Since Caddy 2.11.7 (caddyserver/caddy#7905),
encodecompressestext/event-streamresponses. Each subscriber then holds an encoder for the whole connection (a few MiB with zstd), and compressing tokens or private updates next to attacker-influenced data enables BREACH-style attacks.This excludes the hub path from
encodein the sampleCaddyfileand documents the pattern in the Mercure docs.php-server --mercureisn't affected: its Mercure route runs before the encode route.Same change as dunglas/mercure#1418.