The GitHub Actions job "Validate and test" on 
pekko-http.git/bound-http2-inbound-frame-size has failed.
Run started by GitHub user pjfanning (triggered by pjfanning).

Head commit for run:
edbfd16ea34f0ffff588a159163273de9cae3435 / PJ Fanning 
<[email protected]>
feat: bound the size of an incoming HTTP/2 frame

Motivation:
`Http2FrameParsing` read a frame's 24-bit length field and then took
that many bytes with no upper bound, so a peer could declare a length
up to the field's maximum of 16 MiB - 1 and make the frame parser
buffer that much for a single frame. That happens before the HPACK
and entity limits apply, so `max-header-list-size`,
`incoming-stream-level-buffer-size` and `incoming-connection-level-
buffer-size` do not bound it, and it is multiplied by the number of
connections.

Modification:
Add a `max-frame-size` setting to the HTTP/2 server and client
settings, defaulting to 512kB, and reject a larger frame with a
FRAME_SIZE_ERROR on its frame header, before the payload is buffered.
The value is validated against the bounds RFC 9113, section 4.2 sets
for SETTINGS_MAX_FRAME_SIZE, 16 KiB to 16 MiB - 1.

The setting is a limit on what is accepted, not an advertisement. An
earlier revision did advertise it as SETTINGS_MAX_FRAME_SIZE, which
h2spec's "4.2 Frame Size" case showed to be actively harmful: DATA
frames are flow controlled and the initial window is 64 KiB, so a peer
that sizes its first frame to a larger advertised value trips a
FLOW_CONTROL_ERROR before the window has grown. Advertising nothing
keeps a well-behaved peer at the 16 KiB default it already assumes,
and the configured value is then pure leniency for peers that exceed
it - always accepting at least as much as any peer is told it may
send.

Result:
A single frame can no longer make the parser hold up to 16 MiB; the
bound is 512kB by default and configurable. Frames from a spec
compliant peer are unaffected, and pekko's own existing behaviour of
accepting frames well above 16 KiB is preserved.

Tests:
- sbt "http2-tests/testOnly 
org.apache.pekko.http.impl.engine.http2.Http2ServerSpec 
org.apache.pekko.http.impl.engine.http2.Http2ClientSpec 
org.apache.pekko.http.impl.engine.http2.H2SpecIntegrationSpec" - pass (236 
tests), including the h2spec conformance suite. A new test sends a frame one 
byte over a configured 16 KiB limit and expects GOAWAY(FRAME_SIZE_ERROR); 
verified it fails with the size check disabled. The existing "fail if more data 
is received than stream-level window allows" test deliberately sends a single 
512001 byte frame to exceed the stream buffer, so it now raises max-frame-size 
to 1 MiB to reach the flow-control check it is about.
- sbt http-core/mimaReportBinaryIssues - pass
- sbt "+http-core/compile" - pass on 2.13.18 and 3.3.8

References:
None - bounds how much a single HTTP/2 frame can buffer

Report URL: https://github.com/apache/pekko-http/actions/runs/33416541844

With regards,
GitHub Actions via GitBox


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to