Optimization #8960
openhttp2: improve handling of partially delivered large DATA frames
Description
The HTTP/2 parser uses hard-coded thresholds when handling partially delivered
frames:
```
HTTP2_MAX_HANDLED_FRAME_SIZE = 65536
HTTP2_MIN_HANDLED_FRAME_SIZE = 256
```
For a DATA frame with a declared payload length of at least 65,536 bytes, if
the complete frame is not yet available, the parser waits for at least 256
payload bytes. It then emits `http2.long_frame_data`, processes the available
prefix, and records the number of bytes remaining in the frame. Later input for
that frame is consumed using `request_frame_size` or `response_frame_size`
without being passed through `parse_frames()` and `handle_data_frame()` again.
As a result, HTTP/2 body, file, and decompression inspection only receive the
initially available prefix. The anomaly remains available for detection. This
behavior comes from the parser's bounded handling of large frames, which avoids
buffering an arbitrarily large complete frame.
A reproducer demonstrates this with a protocol-valid 65,536-byte ToServer DATA
frame accepted by stock nginx 1.27-alpine. When the frame is split after the
first 300 body bytes, Suricata emits `http2.long_frame_data`, but content later
in the same frame is not available to body or file-data signatures.
This issue tracks improving this implementation while preserving resource
limits. Possible work includes:
- Process later DATA-frame fragments incrementally through the normal body,
file, and decompression paths where the configured inspection limits allow
it, without buffering the complete frame.
- Apply explicit reassembly, body, file, and decompression limits. If
inspection must stop, emit an event that clearly reports truncation or a
resource limit.
- Keep ToServer and ToClient behavior consistent.
- Evaluate whether the frame-handling thresholds should be configurable and
document the resulting inspection behavior.
- Add a Suricata-Verify test with a valid 65,536-byte DATA frame split across
TCP segments. The test should cover content beyond the initial fragment and
the expected anomaly or truncation events.
Redmine #8410 corrected the direction-specific counter used for large ToClient
frames. It did not change the partial-frame handling described here.
[Credits]
Binbin Xu, Tencent Security YUNDING LAB
JI Updated by Jason Ish about 16 hours ago
- Tracker changed from Feature to Optimization
- Status changed from New to Triaged
JI Updated by Jason Ish about 16 hours ago
- Status changed from Triaged to Assigned
- Assignee changed from OISF Dev to Philippe Antoine