- What Are Compression Side-Channel Attacks?
- How Do CRIME, BREACH, and HEIST Actually Work?
- TLS-Level vs. HTTP-Level Compression: Which Mitigation Applies?
- What Is the Threat Model for Compression Side-Channel Attacks?
- How Do You Mitigate Compression Side-Channel Attacks?
- What Are the Performance and Interoperability Trade-Offs of Disabling Compression?
- What Are the Key Management Dependencies?
- What Do Real-World Deployment Examples Look Like?
- Attack, Vector, and Mitigation: A Decision Table
- Limitations
- What Would Encryption Consulting Recommend?
- Conclusion
- FAQ
A single HTTPS response can leak a secret one byte at a time, not because TLS is broken, but because compression makes ciphertext length reveal information about plaintext content.
Quick answer: Compression side-channel attacks (CRIME, BREACH, HEIST) exploit the fact that compressing a secret together with attacker-controlled input shrinks the output when a guessed character matches, letting an attacker recover CSRF tokens, session identifiers, or other secrets by watching response size, even over encrypted HTTPS. TLS-level compression (CRIME’s vector) is disabled by default in every modern browser and removed outright in TLS 1.3. HTTP-level (gzip/Brotli) compression, BREACH’s actual vector, is still on by default on most web servers and remains exploitable today wherever a secret is reflected alongside user input.
Key takeaways:
- CRIME (2012, CVE-2012-4929) attacked TLS-level compression; it is effectively dead because browsers and TLS 1.3 dropped compression entirely.
- BREACH (2013, CVE-2013-3587) attacks HTTP-level compression (gzip, Brotli, deflate) and is still exploitable on sites that reflect user input next to a static secret.
- HEIST (2016) removed the need for a network position, letting a malicious webpage run these attacks purely through browser timing APIs.
- The fix is rarely “disable all compression.” Separating secrets from reflected input, rotating tokens per request, and rate-limiting are usually cheaper and just as effective.
- Modern browsers and TLS 1.3 close the CRIME-style vector by default; BREACH-style risk is an application-layer problem servers must still handle themselves.
Published: November 2024. Updated: August 2026. Reviewed by Encryption Consulting’s Encryption Advisory team.
In cybersecurity, side-channel attacks exploit the subtle nuances of a computer system’s physical or software-based characteristics rather than a flaw in an algorithm itself. Compression side-channel attacks are a specific, well-documented family of this problem: they turn the length of a compressed HTTPS response into a signal an attacker can measure and exploit, even when the underlying encryption is implemented correctly. Because these attacks target the compression layer, not the cipher, they work against sites that otherwise follow every TLS best practice.
What Are Compression Side-Channel Attacks?
A compression side-channel attack is a technique that recovers secret data by observing the size of a compressed, encrypted response rather than by breaking the encryption itself. Compression algorithms like DEFLATE and gzip work by replacing repeated substrings with shorter back-references, so a piece of text that repeats elsewhere in the same stream compresses to a smaller output than one that does not. If an attacker can inject a guess into the same compression context as a secret, a correct guess makes the compressed output shrink, and an incorrect guess does not. Repeating that process one character at a time turns response length into an oracle for the secret’s contents.
Three conditions have to hold for this to work in practice: the attacker needs a way to inject a chosen guess into the same request or response as the secret, the server needs to compress that combined content, and the attacker needs a way to measure the resulting size, either directly or through TCP-level timing. Remove any one of the three and the attack stops working, which is exactly where mitigation strategies aim.
How Do CRIME, BREACH, and HEIST Actually Work?
CRIME, BREACH, and HEIST are the three attacks that defined this category, and each targets a different layer of the same underlying weakness.
CRIME: TLS-Level Compression (2012)
Researchers Juliano Rizzo and Thai Duong disclosed CRIME (Compression Ratio Info-leak Made Easy, CVE-2012-4929) in September 2012. CRIME targeted TLS-level compression, a feature that compressed the entire TLS record, headers, cookies, and body together, before encryption. An attacker who could run script in the victim’s browser (for example, through a malicious ad or a cross-site request) could inject guessed cookie values into requests and watch the size of the encrypted TLS records to recover a session cookie byte by byte. Because the attack needed a way to observe encrypted traffic size, it typically required a man-in-the-middle or local network position alongside the script-injection capability.
CRIME was patched fast and completely. Chrome and Firefox disabled TLS-level compression within weeks of disclosure, and the IETF removed compression from TLS entirely in TLS 1.3 (RFC 8446). RFC 7457, the IETF’s summary of known TLS attacks, documents CRIME in Section 2.6 alongside the mitigation that ended it: disable TLS-level compression. That mitigation is now the default everywhere, which is why CRIME itself is largely historical.
BREACH: HTTP-Level Compression (2013)
Angelo Prado, Neal Harris, and Yoel Gluck presented BREACH (Browser Reconnaissance and Exfiltration via Adaptive Compression of Hypertext, CVE-2013-3587) at Black Hat USA in August 2013. BREACH moved the same idea up a layer: instead of TLS-level compression, it targets HTTP-level compression, the gzip or Brotli compression almost every web server applies to response bodies regardless of TLS version. That single change is why BREACH still matters. Disabling TLS compression, which killed CRIME, does nothing to stop BREACH.
A BREACH attack needs three things to be true at once, as documented on the researchers’ own breachattack.com and in RFC 7457:
- HTTP-level compression is enabled on the server for the response in question.
- The response reflects some part of the user’s input back in the body (a search term, an error message, a URL parameter).
- A static, guessable secret, such as a CSRF token, session identifier, or an API key, is embedded somewhere in that same response.
With all three present, an attacker who can get the victim’s browser to send repeated cross-site requests (through a malicious page the victim happens to visit) can guess the secret one character at a time by measuring compressed response size, typically recovering a token in well under a minute using a few thousand requests. Because BREACH works over live TLS traffic without ever breaking the encryption, it is invisible to anything watching for cryptographic weaknesses rather than response-length patterns.
HEIST and TIME: Removing the Network Requirement
TIME (Timing Info-leak Made Easy), presented by Tal Be’ery and Amichai Shulman at Black Hat Europe 2013, showed that HTTP-level compression could be attacked using response timing instead of a direct network read, an early step toward removing the man-in-the-middle requirement altogether.
HEIST, presented by Mathy Vanhoef and Tom Van Goethem at Black Hat USA in August 2016, finished that job. HEIST measures how long it takes the Fetch API’s response promise to resolve compared with when the Resource Timing API reports the download finished, which reveals whether a response fit inside a single TCP congestion window (roughly 14 KB) or needed more than one round trip. That measurement is precise enough to run CRIME- and BREACH-style guessing entirely from JavaScript running in the victim’s own browser. No network position, no packet capture, and no man-in-the-middle attacker are required; a malicious or compromised webpage is enough. HEIST is the reason compression side-channel attacks stayed a live topic well past BREACH’s original 2013 disclosure.
TLS-Level vs. HTTP-Level Compression: Which Mitigation Applies?
Picking the right mitigation starts with knowing which layer is doing the compressing, because the two layers need different fixes.
TLS-level compression is the CRIME vector. It is off by default in every current browser, and TLS 1.3 removes the capability from the protocol entirely, so there is effectively nothing left to configure here on a modern stack. If an audit turns up a legacy system still negotiating TLS compression (older embedded devices, unpatched appliances, custom TLS libraries), the fix is to disable it at the TLS library or load balancer configuration and confirm with a protocol-level scan, not to layer on application-side workarounds.
HTTP-level compression is BREACH’s vector, and it is the one that still needs active decisions today. Gzip, Brotli, and zstd are all vulnerable to the same underlying oracle; switching compression algorithms does not fix BREACH, because the weakness is in the “compress secret next to attacker input” pattern, not in any one algorithm’s internals. The real decision is scope: whether to disable compression site-wide, disable it only on routes that mix reflected input with a secret, or keep compression everywhere and remove the secret-reflection pattern instead. Most production sites choose the third option because it preserves performance almost everywhere.
What Is the Threat Model for Compression Side-Channel Attacks?
The attacker needs three capabilities, and the required capability set has narrowed over time rather than widened. First, a way to get the victim’s browser to send many repeated requests, most often by getting the victim to load a malicious or compromised page while an active session exists on the target site. Second, either network visibility into TLS record sizes (CRIME’s original model) or, after HEIST, nothing more than the ability to run JavaScript in the victim’s browser and read standard timing APIs. Third, a target response that reflects attacker-influenced input next to a static, guessable secret, which is squarely an application design problem rather than a TLS configuration problem.
That third requirement is why this threat model matters most for applications that echo query parameters, search terms, or form values back into an HTML page, especially where a CSRF token, session ID, or API key sits in the same page. Static single-page apps with no reflected input, and APIs that never embed a secret in a response body alongside user-controlled content, are largely outside this threat model regardless of whether compression is on.
How Do You Mitigate Compression Side-Channel Attacks?
No single control fully closes this risk on its own; a layered approach works best, applied in roughly this order:
- Confirm TLS-level compression is off. Verify with a TLS scanner or protocol dump that no TLS-level compression method is negotiated. On a TLS 1.3-only stack this is already guaranteed; on any TLS 1.2 fallback path, disable it explicitly at the library or load balancer.
- Separate secrets from reflected content. Never render a CSRF token, session identifier, or API key in the same response body as a value the user (or an attacker acting through the user’s browser) controls. Move the secret to a header, a separate endpoint, or a same-origin-only response.
- Randomize secret-adjacent tokens per request. Generate a fresh, cryptographically random CSRF token or masked value for every request instead of reusing one token for the whole session, so a partial guess learned from one response is worthless against the next.
- Apply length-hiding padding on responses that must mix secrets and reflected input. Adding a random number of padding bytes to the compressed output breaks the precise character-by-character size signal the attack depends on, at a small bandwidth cost.
- Rate-limit and monitor for the guessing pattern. The attack needs a large number of near-identical requests in a short window; rate-limiting repeated requests from the same session and alerting on that pattern raises the cost of the guessing loop significantly.
- Set CSRF cookies as SameSite and disable cross-site compression contexts where practical. Restricting cookies to same-site requests cuts off the cross-origin request pattern most BREACH-style exploitation relies on.
- Disable compression only where the first six steps are not sufficient. For a small number of high-sensitivity routes where secrets and reflected input cannot be architecturally separated, turning compression off for that specific route is a legitimate, targeted last resort.
What Are the Performance and Interoperability Trade-Offs of Disabling Compression?
Disabling HTTP compression is the most complete fix and also the most expensive one. Text-heavy responses, HTML, CSS, JavaScript, and JSON, typically compress to a fraction of their raw size, so turning compression off site-wide can meaningfully increase page weight and load time, which matters most on mobile networks and for users far from the origin or CDN edge. It can also increase origin bandwidth costs at scale, since every response now transfers uncompressed.
Interoperability is a smaller but real concern: some older clients and intermediary proxies expect compressed responses and may behave inconsistently if compression disappears from routes they previously relied on, and CDN or WAF layers that apply their own compression need to be checked so they do not silently re-introduce it after an origin disables it. This is why most teams scope the fix to specific routes, the login flow, the CSRF-protected form submission, the search page that reflects a query string, rather than turning compression off globally. A route-level approach keeps the performance benefit of compression everywhere it is safe and pays the cost only where the threat model actually applies.
What Are the Key Management Dependencies?
Compression side-channel attacks are not a key management vulnerability in themselves, TLS keys and certificates are never the thing being recovered, but the mitigations depend on the same discipline good key management already enforces elsewhere. Randomized, per-request CSRF tokens and masked secrets both require a cryptographically secure random number generator (CSPRNG); an application that already sources randomness from a properly seeded, ideally hardware-backed generator for its signing and session keys should extend that same entropy source to token generation rather than rolling a separate, weaker one.
Session-signing keys and API keys deserve the same rotation discipline as any other credential: short-lived, regularly rotated keys limit how much a partially successful BREACH-style guess is worth, since a recovered token or key expires quickly regardless of the attack’s outcome. Organizations that already manage TLS certificate and key lifecycle through an enterprise PKI program are typically better positioned to extend that same rotation and rate-limiting discipline to application-level secrets, rather than treating CSRF tokens and session keys as a separate, unmanaged category.
What Do Real-World Deployment Examples Look Like?
Most production mitigation happens at the web server or CDN edge, not in application code alone:
- Nginx: scope
gzip off;to the specificlocationblocks that serve authenticated, reflected-input pages, rather than disablinggzipglobally in the server-wide configuration. - Apache: exclude sensitive paths from
mod_deflateusing aSetEnvIfNoCase Request_URIrule matched to the routes that mix secrets and reflected content. - CDN and edge (Cloudflare, Akamai, Fastly, and similar): most CDNs already strip TLS-level compression at the edge by default, which closes CRIME automatically; HTTP-level (gzip/Brotli) compression settings still need to be checked at the origin and edge separately, since an edge can silently re-compress a response the origin intentionally left uncompressed.
- Application layer: frameworks that support per-request CSRF token masking (XOR-ing a per-request token against a fixed session secret before rendering it) let a team keep compression enabled everywhere while still breaking the character-guessing oracle, since the value visible in each response is different every time.
Attack, Vector, and Mitigation: A Decision Table
| Attack | Compression Layer | Network Position Required | Primary Mitigation |
|---|---|---|---|
| CRIME (2012) | TLS-level | Man-in-the-middle plus script injection | Disable TLS-level compression (default in modern browsers; removed in TLS 1.3) |
| TIME (2013) | HTTP-level | Timing measurement, no direct traffic read | Disable HTTP compression or separate secrets from reflected input |
| BREACH (2013) | HTTP-level | Ability to trigger repeated cross-site requests | Separate secrets from reflected input; per-request token randomization; rate-limiting |
| HEIST (2016) | HTTP-level (via TCP window timing) | None; runs from malicious JavaScript in-browser | Same as BREACH, plus length-hiding padding and SameSite cookies |
Limitations
These mitigations reduce risk; they do not make it disappear entirely, and it helps to be precise about what they do not cover. Route-level compression exclusions only protect the routes an engineering team actually identifies and configures, so an unreviewed new endpoint that reflects input next to a secret reintroduces the exact same weakness. Per-request token randomization stops BREACH-style guessing but does nothing for a secret an attacker obtains through an unrelated flaw, such as a logging leak or an XSS vulnerability. Rate-limiting slows an attacker down; a patient one operating over a longer window, or one distributing requests across many source IPs, can still make progress against a target that is otherwise unmonitored. None of these controls substitute for a broader application security review, and none of them address secrets that never touch a compressed response in the first place, such as database credentials or private keys, which need their own, separate protections.
What Would Encryption Consulting Recommend?
Start with an inventory question, not a configuration change: which of your responses reflect user input and carry a static secret in the same body. That is a smaller list than most teams expect, and it is the actual attack surface. Encryption Consulting’s Encryption Advisory Services team helps organizations run that inventory, prioritize routes by exposure, and select the right mix of token randomization, length-hiding padding, and scoped compression exclusions rather than defaulting to a blanket “disable compression everywhere” policy that costs performance without matching the actual risk.
Where the underlying issue traces back to how session keys, signing keys, or certificate-backed identities are generated and rotated, our PKI Services team helps design certificate policies (CP/CPS) and key lifecycle practices that extend the same rotation and randomness discipline to application-level secrets, so CSRF tokens and session identifiers stop being the weakest link in an otherwise well-run TLS deployment. In an environment where encryption alone isn’t enough, closing this gap is usually a matter of a focused architecture review, not a rebuild.
Conclusion
CRIME showed that compression could leak secrets through TLS itself, and the industry closed that door by killing TLS-level compression outright. BREACH showed the same weakness one layer up, in the HTTP compression nearly every server still applies, and HEIST proved an attacker does not even need network access to exploit it. None of this means encryption failed; it means that compression and confidentiality make uncomfortable neighbors whenever a secret shares a response with content an attacker can influence. Separating the two, randomizing what cannot be separated, and rate-limiting the guessing loop closes the gap without giving up the performance benefit of compression everywhere else.
FAQ
Is TLS-level compression still a real risk in 2026?
No. Every current major browser disables TLS-level compression, and TLS 1.3 (RFC 8446) removes compression from the protocol entirely. CRIME’s specific vector is closed by default on any modern stack; it only resurfaces on legacy systems still negotiating older TLS versions with compression enabled.
Does BREACH still work against HTTPS websites today?
Yes, wherever the three preconditions hold: HTTP-level compression is enabled, the response reflects user input, and a static secret sits in that same response. BREACH does not depend on TLS version and is not fixed by upgrading to TLS 1.3, since it targets HTTP-level compression, not the TLS layer.
Do we have to disable compression to be safe?
No, and for most sites it is not the recommended first step. Separating secrets from reflected content and randomizing tokens per request closes the same gap while keeping the performance benefit of compression on every other route.
Can an attacker run this without intercepting our network traffic?
Yes, since HEIST (2016). By measuring browser timing APIs, an attacker running JavaScript on any page the victim visits, no man-in-the-middle position required, can infer response sizes precisely enough to carry out a BREACH-style guess.
Is switching from gzip to Brotli a fix?
No. The vulnerability comes from compressing a secret alongside attacker-controlled input, a pattern common to every general-purpose compression algorithm, including gzip, Brotli, and zstd. Changing algorithms does not remove the oracle.
References
- Rizzo, J. and Duong, T., “CRIME” disclosure and CVE-2012-4929, reported via Threatpost (September 2012).
- Prado, A., Harris, N., and Gluck, Y., “BREACH: Reviving the CRIME Attack,” Black Hat USA 2013, official mitigation guidance at breachattack.com.
- Vanhoef, M. and Van Goethem, T., “HEIST: HTTP Encrypted Information Can Be Stolen Through TCP-Windows,” Black Hat USA 2016, full whitepaper (PDF).
- IETF, RFC 7457, “Summarizing Known Attacks on Transport Layer Security (TLS) and Datagram TLS (DTLS)”, Section 2.6.
- IETF, RFC 8446, “The Transport Layer Security (TLS) Protocol Version 1.3”, on the removal of compression from TLS.
- What Are Compression Side-Channel Attacks?
- How Do CRIME, BREACH, and HEIST Actually Work?
- TLS-Level vs. HTTP-Level Compression: Which Mitigation Applies?
- What Is the Threat Model for Compression Side-Channel Attacks?
- How Do You Mitigate Compression Side-Channel Attacks?
- What Are the Performance and Interoperability Trade-Offs of Disabling Compression?
- What Are the Key Management Dependencies?
- What Do Real-World Deployment Examples Look Like?
- Attack, Vector, and Mitigation: A Decision Table
- Limitations
- What Would Encryption Consulting Recommend?
- Conclusion
- FAQ
