HTTP/2 Security Testing: Request Smuggling, Header Injection, and Protocol Attacks

HTTP/2 now carries the majority of web traffic. Most major applications, CDNs, and reverse proxies support it by default. But the same features that make HTTP/2 faster — binary framing, stream multiplexing, header compression — introduce a new class of vulnerabilities that don't exist in HTTP/1.1. The most severe is HTTP/2 request smuggling, which allows attackers to poison shared connection state between a front-end proxy and a back-end server, leading to request hijacking, cache poisoning, and authentication bypass.

This guide covers the practical mechanics of HTTP/2 security testing: how the protocol differs from HTTP/1.1, where the attack surface lives, and how to test it systematically.

HTTP/2 Protocol Fundamentals for Security Testers

Understanding the attack surface requires understanding what HTTP/2 changed from HTTP/1.1:

Feature HTTP/1.1 HTTP/2 Security Implication
Framing Text-based Binary frames Harder to inspect manually; proxy translation bugs
Multiplexing Sequential or pipelined Multiple streams per connection Stream state confusion; cross-stream data leakage
Header compression None HPACK compression CRIME-like compression oracle attacks
Content-Length Required for body size Determined by framing H2.CL desync when proxies downgrade to HTTP/1.1
Transfer-Encoding Chunked encoding valid Forbidden in spec H2.TE desync if back-end accepts it
Pseudo-headers Not applicable :method, :path, :authority, :scheme Header injection via malformed pseudo-headers

The most important architectural fact for security testing: most HTTP/2 deployments use a TLS-terminating front-end that speaks HTTP/2 to clients, then translates to HTTP/1.1 for back-end communication. This translation layer is where the most critical vulnerabilities live.

HTTP/2 Request Smuggling

HTTP/2 request smuggling exploits discrepancies between how a front-end proxy interprets the end of one HTTP/2 request and how a back-end server (receiving a translated HTTP/1.1 request) interprets the same boundary. James Kettle's research (PortSwigger, 2021) revealed that this class of attack is significantly more prevalent than HTTP/1.1 smuggling.

H2.CL (HTTP/2 with Content-Length)

The HTTP/2 spec forbids Content-Length from mismatching frame length, but many implementations accept it anyway. When the front-end translates to HTTP/1.1, it forwards the Content-Length header to the back-end. If the values differ, the back-end interprets the remaining bytes as the start of the next request.

H2.CL Attack Pattern Send an HTTP/2 request with a Content-Length header smaller than the actual body. The front-end uses HTTP/2 framing (correct length); the back-end uses the forwarded Content-Length (short), treating the remaining body bytes as the beginning of the next request on the connection.

Testing with Burp Suite's HTTP/2 support:

POST / HTTP/2
Host: target.com
Content-Length: 0

GET /admin HTTP/1.1
Host: target.com
Foo: bar

If the back-end interprets the smuggled prefix, the next legitimate request on that connection will have the GET /admin prefix prepended to it — potentially giving the attacker's path or headers precedence.

H2.TE (HTTP/2 with Transfer-Encoding)

The HTTP/2 spec explicitly prohibits Transfer-Encoding headers, but some front-ends pass them through anyway when translating to HTTP/1.1. If the back-end processes chunked transfer encoding, a desync becomes possible:

POST / HTTP/2
Host: target.com
Transfer-Encoding: chunked

0

GET /admin HTTP/1.1
Host: internal.target.com

Test for H2.TE by injecting Transfer-Encoding: chunked directly in Burp's HTTP/2 editor. Check whether the front-end strips, passes, or rejects it.

CRLF Injection via HTTP/2 Header Values

HTTP/2 binary framing means header values can contain bytes that would be illegal in HTTP/1.1 — including CR (\r) and LF (\n). When a front-end translates these to HTTP/1.1 headers without sanitization, an attacker can inject additional HTTP/1.1 headers or terminate the header block early:

:method: GET
:path: /
:authority: target.com
foo: bar\r\nTransfer-Encoding: chunked

After translation to HTTP/1.1, this becomes:

GET / HTTP/1.1
Host: target.com
foo: bar
Transfer-Encoding: chunked

Burp Suite's HTTP/2 editor allows sending raw CRLF sequences in header values. Test systematically across all user-controllable headers.

HPACK Header Compression Attacks

HPACK is HTTP/2's header compression scheme. It maintains a dynamic table of previously seen header name-value pairs and references them by index in subsequent requests. This creates a compression oracle: if an attacker can inject controlled data alongside a secret value in the same compressed block, they can infer the secret by observing compressed size differences — the same principle as CRIME (against TLS compression) but applied at the HTTP layer.

Practical HPACK Oracle Conditions

For a HPACK oracle attack to work:

  1. The application must compress headers containing attacker-controlled data alongside secret data in the same HPACK context
  2. The attacker must be able to observe compressed payload sizes (e.g., via a side channel or direct network access)
  3. TLS must not be used, OR the attacker controls the TLS layer (e.g., testing from the network layer)

In practice, HPACK oracles are most relevant in server-to-server HTTP/2 communication over non-TLS transports, or in environments where an attacker has network-level access to observe packet sizes.

Server Push Security Issues

HTTP/2 server push allows a server to proactively send resources to the client before they are requested. Chrome and other major browsers deprecated and removed support for server push in 2022, but server-side implementations remain in many frameworks. Server push creates several potential security issues:

Test server push by inspecting HTTP/2 frames directly with h2spec, Wireshark with SSL key logging, or Burp's HTTP/2 tools. Look for PUSH_PROMISE frames and evaluate what's being pushed and to whom.

Stream Multiplexing and State Confusion

HTTP/2 multiplexes multiple logical streams over a single TCP connection. Each stream has independent state (headers, flow control windows, priority). Bugs in stream state management can create cross-stream data leakage:

Stream Reset Abuse (CVE-2023-44487 — HTTP/2 Rapid Reset)

The Rapid Reset vulnerability, disclosed in October 2023, exploited the ability to send a stream and immediately cancel it with RST_STREAM. By sending hundreds of thousands of rapid stream-open/cancel sequences, an attacker could exhaust server resources without completing requests — a highly efficient application-layer DoS that bypassed rate limiting based on completed requests.

Testing for Rapid Reset exposure:

Flow Control Window Abuse

HTTP/2 uses flow control windows to prevent a fast sender from overwhelming a slow receiver. Misconfigurations in window sizes can be exploited for resource exhaustion or to create timing side channels. Test by inspecting WINDOW_UPDATE frame behavior under load.

Protocol Downgrade and Negotiation Attacks

HTTP/2 is negotiated via ALPN (Application-Layer Protocol Negotiation) during TLS handshake, or via the Upgrade header for non-TLS connections (h2c). Forcing a downgrade to HTTP/1.1 can bypass HTTP/2-specific security controls:

Testing ALPN Negotiation

# Check what protocols the server supports
openssl s_client -connect target.com:443 -alpn h2 2>&1 | grep -E "(ALPN|Protocol)"

# Enumerate via nmap
nmap -sV --script ssl-enum-ciphers -p 443 target.com

# h2spec for HTTP/2 compliance testing
h2spec -h target.com -p 443 -t

h2c Upgrade Security

Cleartext HTTP/2 (h2c) using the HTTP Upgrade mechanism should not be enabled on production endpoints. It exposes all the HTTP/2 attack surface without TLS protection:

GET / HTTP/1.1
Host: target.com
Connection: Upgrade, HTTP2-Settings
Upgrade: h2c
HTTP2-Settings: AAMAAABkAAQAAP__

If the server responds with 101 Switching Protocols, h2c is enabled. This should be flagged unless there's a specific technical justification (e.g., internal load balancer communication).

Testing HTTP/2 with Burp Suite

Burp Suite Pro (from version 2021.9) includes first-class HTTP/2 support. Key capabilities:

# Manual H2.CL test in Burp HTTP/2 editor
# Add Content-Length header with value shorter than body
# Body: [prefix of smuggled request]

# HTTP Request Smuggler automated scan
# Extensions > HTTP Request Smuggler > Active Scan
# Covers: CL.TE, TE.CL, H2.CL, H2.TE, H2.0

HTTP/3 (QUIC) Security Considerations

HTTP/3 replaces TCP with QUIC (UDP-based). The attack surface shifts:

Attack Class HTTP/2 (TCP) HTTP/3 (QUIC)
Request smuggling H2.CL, H2.TE via proxy translation Different framing reduces classic vectors; new variants emerging
Connection-level DoS TCP reset, SYN flood UDP amplification, QUIC Initial packet flooding
Protocol confusion HTTP/1.1 downgrade Alt-Svc header spoofing to redirect to attacker-controlled h3 endpoint
Connection migration abuse Not applicable QUIC connection migration can be abused to hijack sessions

HTTP/3 tooling is less mature. Use curl --http3, quiche (Cloudflare), or ngtcp2 for protocol-level testing.

HTTP/2 Security Testing Checklist

Ironimo runs Kali Linux-grade security scanning — including protocol-level HTTP/2 vulnerability detection — on demand. No manual proxy setup, no custom scripts.

Start free scan
← Back to Blog