Project

General

Profile

Actions

Bug #8581

open
JI OD

http2: HPACK varint overflow can cause IDS evasion

Bug #8581: http2: HPACK varint overflow can cause IDS evasion

Added by Jason Ish 5 days ago. Updated about 10 hours ago.

Status:
Feedback
Priority:
Normal
Assignee:
Target version:
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)
Actions

Also available in: PDF Atom