Project

General

Profile

Actions

Bug #8410

closed
PA PA

http2: response_frame_size is never set

Bug #8410: http2: response_frame_size is never set

Added by Philippe Antoine 28 days ago. Updated 22 days ago.

Status:
Closed
Priority:
Normal
Target version:
Affected Versions:
Effort:
Difficulty:
Label:

Description

request_frame_size is set whatever the direction

Setting request_frame_size when we should set response_frame_size leads to FN

Submitted report:

[Summary]
`HTTP2State::parse_frames()` is called for both ToServer and ToClient directions, but unconditionally writes remaining frame bytes to `self.request_frame_size` (line 1153 of `rust/src/http2/http2.rs`). When a large (>=65536 bytes) server-to-client DATA frame is partially delivered, the remaining byte count is stored in `request_frame_size` instead of `response_frame_size`. On the next client-to-server data delivery, `parse_ts()` consumes `request_frame_size` bytes and discards them, causing all subsequent client HTTP/2 requests to be silently dropped from parsing and inspection.

[Root Cause]
`HTTP2State` maintains two fields for tracking remaining bytes of partially-delivered large frames:

```rust
// rust/src/http2/http2.rs:567-568
pub struct HTTP2State {
request_frame_size: u32, // used by parse_ts() at line 1343
response_frame_size: u32, // used by parse_tc() at line 1369
...
}
```

`parse_ts()` (ToServer) checks and consumes `self.request_frame_size` at lines 1343-1352. `parse_tc()` (ToClient) checks and consumes `self.response_frame_size` at lines 1369-1378. Both call the shared `parse_frames()` method.

Inside `parse_frames()`, when a frame with `length >= HTTP2_MAX_HANDLED_FRAME_SIZE` (65536) arrives partially (the available data contains at least `HTTP2_MIN_HANDLED_FRAME_SIZE` (256) bytes but not the full frame), line 1153 executes:

```rust
// rust/src/http2/http2.rs:1153
self.request_frame_size = head.length - (rem.len() as u32);
```

This always writes to `request_frame_size`, even when `parse_frames()` was called from `parse_tc()` with `dir Direction::ToClient`. The correct behavior would be:

```rust
if dir Direction::ToServer {
self.request_frame_size = head.length - (rem.len() as u32);
} else {
self.response_frame_size = head.length - (rem.len() as u32);
}
```

[PoC]
Please extract the attached compressed file and proceed.

1. docker build -t poc .
2. docker run --rm poc
스크린샷 2026-03-24 오후 9.51.45.png

[Impact]
- All client requests following a large server response are invisible to Suricata's detection engine. HTTP-based signature rules (`http.uri`, `http.method`, `http.request_header`, etc.) fail to match.
- This is trivially exploitable by any server an attacker controls. HTTP/2 responses >= 64KB are extremely common in normal web traffic.
- HTTP/2 is enabled by default in Suricata (`app-layer.protocols.http2.enabled: yes`).

[Affected Version]
  • Current `main` branch (commit bc4a055e7, Suricata 9.0.0-dev) is confirmed affected.

Files


Subtasks 1 (0 open1 closed)

Bug #8411: http2: response_frame_size is never set (8.0.x backport)ClosedPhilippe AntoineActions

OT Updated by OISF Ticketbot 28 days ago Actions #1

  • Subtask #8411 added

OT Updated by OISF Ticketbot 28 days ago Actions #2

  • Label deleted (Needs backport to 8.0)

PA Updated by Philippe Antoine 28 days ago Actions #3

  • Status changed from Assigned to In Progress
  • Label Needs backport to 7.0 added

Gitlab MR

I think this can be made public as a regular bug

This needs complicity between client and server to evade client detection, so not a security issue for me

OT Updated by OISF Ticketbot 28 days ago Actions #4

  • Subtask #8412 added

OT Updated by OISF Ticketbot 28 days ago Actions #5

  • Label deleted (Needs backport to 7.0)

PA Updated by Philippe Antoine 28 days ago Actions #6

  • Status changed from In Progress to In Review

VJ Updated by Victor Julien 27 days ago Actions #8

  • Private changed from Yes to No

We will consider this to be a regular bug as to use this to evade Suricata it would need the attacker to control both the server and client to cooperate on this.

PA Updated by Philippe Antoine 23 days ago Actions #10

  • Status changed from In Review to Resolved

PA Updated by Philippe Antoine 22 days ago Actions #11

  • Status changed from Resolved to Closed
Actions

Also available in: PDF Atom