Actions
Bug #8581
open
JI
OD
http2: HPACK varint overflow can cause IDS evasion
Bug #8581:
http2: HPACK varint overflow can cause IDS evasion
Affected Versions:
Effort:
Difficulty:
Label:
Needs Suricata-Verify test
Description
Summary
The function http2_parse_var_uint in rust/src/http2/parser.rs:459-481 silently
returns value=0 when an HPACK-encoded integer overflows u64 (encoded in ≥10
continuation bytes). Instead of returning an error, the parser returns
Ok((remaining_input,
0)), which propagates through the HTTP/2 header decoding pipeline and
causes Suricata to interpret headers differently from the actual HTTP/2
server.
This allows an attacker to craft HTTP/2 HEADERS frames that evade Suricata
detection rules by making the IDS see empty or incorrect header values
while the destination server processes the intended values.
Severity
Medium — IDS evasion. No crash or memory corruption, but allows malicious
HTTP/2 traffic to bypass detection rules.
Vulnerable Code
rust/src/http2/parser.rs:459-481:
rust
fn http2_parse_var_uint(input: &[u8], value: u64, max: u64) ->
IResult<&[u8], u64> {
// ...
if varia.len() > 9 || (varia.len() == 9 && finalv > 1) {
// this will overflow u64
return Ok((i3, 0)); // ← silently returns 0 instead of error
}
// ...}
Affected Downstream Functions
The value=0 propagates to:
1. *http2_parse_headers_block_indexed* (line 318): index 0 triggers
HTTP2HeaderDecodeIndex0 — the header is silently ignored by Suricata
while the server processes it normally.
2. *http2_parse_headers_block_string* (line 330): stringlen=0 results in
an empty string — Suricata sees an empty header value while the server sees
the real value.
3. *Literal headers with incremental indexing* (lines 384, 439, 454):
value 0 is interpreted as "new header entry" instead of the actual index,
causing incorrect HPACK dynamic table state divergence between Suricata and
the server.
Steps to Reproduce
1. Set up Suricata monitoring HTTP/2 traffic with a detection rule
matching a specific URI or Host header
2. From a client, send an HTTP/2 HEADERS frame containing an
HPACK-encoded header where the integer value uses ≥10 continuation bytes
(forcing the overflow path)
3. The destination server (which implements HPACK per RFC 7541) will
either:
- Decode the value correctly (if within its integer size), or
- Return a COMPRESSION_ERROR (per spec)
4. Suricata will silently decode the value as 0 and process the header
as empty/indexed-at-0
Example: encode a header index that, when properly decoded, points to :path:
/malicious but when decoded as 0 by Suricata, is ignored entirely.
Suricata's rule for /malicious does not fire.
Impact
1. *Detection bypass*: An attacker can hide malicious HTTP/2 request
headers (URI, Host, User-Agent, Cookie) from Suricata rules by encoding
them with overflowing HPACK integers. The destination server processes the
real headers while Suricata sees empty values.
2. *HPACK dynamic table desynchronization*: When the overflow occurs in
a literal-with-incremental-indexing header, Suricata's HPACK dynamic table
state diverges from the server's. All subsequent headers in the connection
may be decoded incorrectly by Suricata, amplifying the evasion window.
3. *Silent failure*: There is no log entry, alert, or anomaly event when
the overflow occurs. The parser returns success with corrupted data.
Suggested Fix
Return an error instead of silently accepting the overflow:
rust
if varia.len() > 9 || (varia.len() == 9 && finalv > 1) {
// this will overflow u64
return Err(nom::Err::Error(nom::error::make_error(input,
nom::error::ErrorKind::LengthValue)));}
This matches the error handling pattern already used in the checked_add branch
at lines 474-476 of the same function.
Environment
- Suricata main branch @ commit 367ca7f (post v8.0.1, May 15, 2026)
- Affected file: rust/src/http2/parser.rs
- Feature: HTTP/2 HPACK header decoding (enabled by default)
PA Updated by Philippe Antoine 5 days ago
- Status changed from New to Feedback
- Label Needs Suricata-Verify test added
Waiting on a SV reproducer, with an actual HTTP/2 server
I think this is just a bug, not a security issue
PA Updated by Philippe Antoine about 10 hours ago
- Tracker changed from Security to Bug
- Private changed from Yes to No
- Disclosure Date deleted (
05/19/2026)
Still waiting on a SV reproducer, I am not sure there is a bug...
Actions