Skip to content

Unify header-size limits into one MAX_HEADER_LIST_SIZE - #44

Open
ulfjack wants to merge 1 commit into
ulfjack/sec-hardening-6from
ulfjack/sec-hardening-7
Open

Unify header-size limits into one MAX_HEADER_LIST_SIZE#44
ulfjack wants to merge 1 commit into
ulfjack/sec-hardening-6from
ulfjack/sec-hardening-7

Conversation

@ulfjack

@ulfjack ulfjack commented Aug 10, 2026

Copy link
Copy Markdown
Owner

Received-message header limits were scattered across eight arbitrary
constants with inconsistent values: per-name (1000 vs 1024), per-value
(10000 vs 4096), and per-field-count caps in the two HTTP/1 parsers, plus an
8 KB merged-value cap in each builder. The old request scheme was also
effectively unbounded in aggregate (10 KB x 1000 fields ~= 10 MB).

Replace them all with one shared limit, HttpLimits.MAX_HEADER_LIST_SIZE (32
KiB) — the value HTTP/2 already advertises as SETTINGS_MAX_HEADER_LIST_SIZE.
Both HTTP/1 parsers now enforce a single running budget over the header
section (sum of field name+value sizes, checked at the append sites); HTTP/2
already enforces the same total during HPACK decode, now sharing the
constant. So the limit means the same thing everywhere.

Applied to received messages only: requests and origin responses are
bounded; responses we generate are not. The builders' merged-value caps are
gone (the O(n) StringBuilder accumulator stays — a received merged value is
bounded by the parser's total, a generated one is intentionally unbounded).

Net: 8 constants -> 1.

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

Received-message header limits were scattered across eight arbitrary
constants with inconsistent values: per-name (1000 vs 1024), per-value
(10000 vs 4096), and per-field-count caps in the two HTTP/1 parsers, plus an
8 KB merged-value cap in each builder. The old request scheme was also
effectively unbounded in aggregate (10 KB x 1000 fields ~= 10 MB).

Replace them all with one shared limit, HttpLimits.MAX_HEADER_LIST_SIZE (32
KiB) — the value HTTP/2 already advertises as SETTINGS_MAX_HEADER_LIST_SIZE.
Both HTTP/1 parsers now enforce a single running budget over the header
section (sum of field name+value sizes, checked at the append sites); HTTP/2
already enforces the same total during HPACK decode, now sharing the
constant. So the limit means the same thing everywhere.

Applied to received messages only: requests and origin responses are
bounded; responses we generate are not. The builders' merged-value caps are
gone (the O(n) StringBuilder accumulator stays — a received merged value is
bounded by the parser's total, a generated one is intentionally unbounded).

Net: 8 constants -> 1.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ulfjack
ulfjack force-pushed the ulfjack/sec-hardening-6 branch from 05874d6 to fec9069 Compare August 10, 2026 17:16
@ulfjack
ulfjack force-pushed the ulfjack/sec-hardening-7 branch from ff1d225 to 6573e41 Compare August 10, 2026 17:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant