# How to Test for TLS Compression Vulnerabilities (CRIME & BREACH) with testssl.sh

> Easily test for TLS compression vulnerabilities like CRIME and BREACH using the testssl.sh tool. Learn how to secure your servers by identifying and mitigating these risks.

- Repository: [Dirk Wetter/testssl.sh](https://github.com/drwetter/testssl.sh)
- Tags: how-to-guide
- Published: 2026-03-01

---

**Use `./testssl.sh --crime` to detect TLS-level compression (CRIME) and `./testssl.sh --breach` to detect HTTP-level compression (BREACH) on any target host.**

Testing for TLS compression vulnerabilities is a critical step in securing web servers against information leakage attacks. The [`drwetter/testssl.sh`](https://github.com/drwetter/testssl.sh/blob/main/drwetter/testssl.sh) repository provides specialized command-line flags to detect both CRIME and BREACH vulnerabilities through automated TLS handshake analysis and HTTP header inspection. This guide explains how to use testssl.sh to identify these compression-related security flaws.

## Understanding TLS Compression Attacks

Before running the tests, it is important to distinguish between the two compression vulnerabilities that testssl.sh detects.

### What is CRIME?

**CRIME** (Compression Ratio Info-leak Made Easy) exploits TLS-level compression (typically zlib) supported in TLS 1.2 and earlier. When a server accepts compressed TLS records, an attacker can inject chosen plaintext into a victim's requests and observe the compressed response size to recover session cookies or tokens.

### What is BREACH?

**BREACH** (Browser Reconnaissance and Exfiltration via Adaptive Compression of Hypertext) targets HTTP-level compression (gzip, deflate, or brotli) rather than TLS compression. Even when TLS compression is disabled, HTTP compression of response bodies can leak secrets through similar side-channel techniques if the response contains both attacker-controlled input and secret tokens.

## Testing for CRIME with testssl.sh

The `test_crime` function in [`testssl.sh`](https://github.com/drwetter/testssl.sh/blob/main/testssl.sh) (lines 18184–18242) implements the CRIME detection logic by manipulating the TLS handshake to force a compression method disclosure.

### How the CRIME Test Works

According to the source code in [`drwetter/testssl.sh`](https://github.com/drwetter/testssl.sh/blob/main/drwetter/testssl.sh), the script performs the following steps:

1. **Disables client compression advertisement**: The script sets `offer_compression=false` in the ClientHello, explicitly telling the server that the client does not support TLS compression.
2. **Inspects the ServerHello**: After the handshake, the script extracts the `tls_compression_method` field from the ServerHello response.
3. **Evaluates vulnerability**: If the server selects any compression method other than `null` (0x00), the test reports **Vulnerable to CRIME** and caps the overall grade at *C*.

### Running the CRIME Test

Execute the following command to check for TLS compression vulnerabilities:

```bash
./testssl.sh --crime example.com:443

```

For mail servers using IMAPS or other TLS-wrapped protocols:

```bash
./testssl.sh --crime imap.example.org:993

```

The console output will display:

```

CRIME, TLS (Vulnerable to CRIME)

```

If vulnerable, or:

```

CRIME, TLS (Not vulnerable)

```

If the server correctly rejects compression.

## Testing for BREACH with testssl.sh

The `test_breach` function (lines 18318–18344) in [`testssl.sh`](https://github.com/drwetter/testssl.sh/blob/main/testssl.sh) detects HTTP-level compression by analyzing response headers rather than TLS handshake parameters.

### How the BREACH Test Works

The BREACH detection logic in [`drwetter/testssl.sh`](https://github.com/drwetter/testssl.sh/blob/main/drwetter/testssl.sh) operates as follows:

1. **Sends compression-capable request**: The script transmits an HTTP GET request including an `Accept-Encoding` header listing all common compression algorithms: `gzip`, `deflate`, `compress`, and `br` (brotli).
2. **Analyzes response headers**: The script inspects the HTTP response for a `Content-Encoding` header.
3. **Determines vulnerability**: If the server returns any compression encoding, the test flags **Vulnerable to BREACH**; otherwise, it reports **No HTTP compression (OK)**.

### Running the BREACH Test

To check for HTTP compression vulnerabilities:

```bash
./testssl.sh --breach https://example.com/

```

You can combine both compression tests in a single invocation:

```bash
./testssl.sh --crime --breach example.com:443

```

The output will indicate:

```

BREACH (gzip HTTP compression)

```

Or if safe:

```

BREACH (no gzip/deflate/compress/br HTTP compression (OK))

```

## Interpreting JSON Output

When using the `--json` or `--jsonfile` options, [`testssl.sh`](https://github.com/drwetter/testssl.sh/blob/main/testssl.sh) exports structured results with specific identifiers:

```json
{
  "CRIME_TLS": {
    "severity": "CRITICAL",
    "description": "Vulnerable to CRIME"
  },
  "BREACH": {
    "severity": "CRITICAL",
    "description": "gzip HTTP compression"
  }
}

```

These `jsonID` values allow automated security scanners to parse compression vulnerability status without parsing human-readable text.

## Summary

- **CRIME** attacks TLS-level compression (zlib), while **BREACH** exploits HTTP-level compression (gzip/deflate/br).
- Use `./testssl.sh --crime` to detect TLS compression by analyzing the ServerHello response for non-null compression methods (source: [`testssl.sh`](https://github.com/drwetter/testssl.sh/blob/main/testssl.sh) lines 18184–18242).
- Use `./testssl.sh --breach` to detect HTTP compression by checking for `Content-Encoding` headers in HTTP responses (source: [`testssl.sh`](https://github.com/drwetter/testssl.sh/blob/main/testssl.sh) lines 18318–18344).
- Both tests set `severity` to `CRITICAL` in JSON output when vulnerabilities are detected, with CRIME additionally capping the overall grade at *C*.

## Frequently Asked Questions

### What is the difference between CRIME and BREACH?

**CRIME** targets compression at the TLS protocol level (specifically the DEFLATE algorithm used in TLS compression), allowing attackers to recover session cookies by observing the size of compressed TLS records. **BREACH** targets compression at the HTTP application level (gzip, deflate, or brotli), exploiting the fact that HTTP responses often contain both attacker-controlled input and secret tokens. While CRIME requires TLS compression to be enabled, BREACH can affect any HTTPS site that compresses HTTP responses regardless of TLS settings.

### Does testssl.sh require root privileges to test for compression vulnerabilities?

No, testing for CRIME and BREACH with [`testssl.sh`](https://github.com/drwetter/testssl.sh/blob/main/testssl.sh) does not require root privileges. The script operates as a standard TLS client using OpenSSL's `s_client` command for the CRIME test and standard HTTP GET requests for the BREACH test. However, if you are scanning ports below 1024 on the local machine or need to bind to specific local ports, elevated privileges might be necessary, but this is not specific to compression testing.

### How does testssl.sh detect CRIME without offering compression?

The `test_crime` function in [`testssl.sh`](https://github.com/drwetter/testssl.sh/blob/main/testssl.sh) (lines 18184–18242) deliberately sets `offer_compression=false` in the ClientHello to signal that the client does not support TLS compression. According to the TLS specification, if the server respects this and only supports compression, it should either select `null` compression (0x00) or abort the handshake. The script then inspects the ServerHello response; if the server selects any non-null compression method despite the client's refusal, [`testssl.sh`](https://github.com/drwetter/testssl.sh/blob/main/testssl.sh) reports the server as vulnerable to CRIME.

### Can BREACH be mitigated while keeping HTTP compression enabled?

Mitigating BREACH while maintaining HTTP compression is challenging because the vulnerability fundamentally relies on the side-channel created by compression. According to the [`drwetter/testssl.sh`](https://github.com/drwetter/testssl.sh/blob/main/drwetter/testssl.sh) source code documentation and security best practices, effective mitigations include implementing CSRF tokens that change per request (breaking the attack's ability to guess secrets across multiple requests), separating secrets from attacker-controlled input in the response body, or using length-hiding techniques. However, the only definitive fix is disabling HTTP compression entirely, which [`testssl.sh`](https://github.com/drwetter/testssl.sh/blob/main/testssl.sh) identifies when the server returns no `Content-Encoding` header in response to the BREACH test probe.