Skip to content

Count HPACK header list entries with RFC 9113 per-entry overhead - #9733

Open
shaggyinsomniac wants to merge 1 commit into
lysine-dev:mainfrom
shaggyinsomniac:hpack-header-limit
Open

Count HPACK header list entries with RFC 9113 per-entry overhead#9733
shaggyinsomniac wants to merge 1 commit into
lysine-dev:mainfrom
shaggyinsomniac:hpack-header-limit

Conversation

@shaggyinsomniac

Copy link
Copy Markdown

Problem

The header list byte limit in Hpack.Reader was computed as name.size + value.size, so a literal header field whose name and value are both empty contributed zero bytes to the accounting:

00 00 00   // Literal Header Field without Indexing, name length 0, value length 0

A peer can send HEADERS/CONTINUATION frames (not flow controlled) composed of these 3-byte entries and grow the header list indefinitely — one Header object per 3 wire bytes, roughly 30-50x heap amplification — without the 256 KiB HEADER_LIMIT ever being exceeded. MAX_HEADER_LIST_SIZE is not enforced ("Advisory only" in Http2Reader), so this is the only cap. Same class of issue as CVE-2024-27316 (nghttp2 CONTINUATION flood).

Fix

Account for the 32-byte per-entry overhead defined by RFC 9113 §6.5.2 when a header is added, matching nghttp2 and Jetty. Every header entry now consumes budget regardless of name/value length, so zero-length entries cannot bypass the limit.

Test

manyEmptyHeadersExceedByteLimit — sends 8193 zero-length literal headers (24 KiB) and expects the reader to throw. Fails on master (the limit never trips) and passes with this change. Full HpackTest suite (58 tests) passes.

The header list byte limit was computed as name.size + value.size, so a
literal header field whose name and value are both empty contributed
nothing to the accounting. A peer could send CONTINUATION frames (which
are not flow controlled) containing 3-byte zero-length literal headers
and grow the header list without the limit ever being exceeded.

Account for the 32-byte per-entry overhead defined by RFC 9113 section
6.5.2, matching nghttp2 and Jetty, so every header entry consumes budget
and the limit cannot be bypassed with empty entries.

Signed-off-by: Sagar Chanchal <Sagarr2112@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant