SABITHSAHEB opened a new pull request, #14009:
URL: https://github.com/apache/trafficserver/pull/14009

   1. `Http3SettingsFramer` advertises 
`proxy.config.http3.max_field_section_size` (4096 by default), but 
`Http3Session` builds the decoder (`_remote_qpack`) with 
`HTTP3_DEFAULT_MAX_FIELD_SECTION_SIZE` (UINT32_MAX), and `Http3SettingsHandler` 
then copies the client's own SETTINGS_MAX_FIELD_SECTION_SIZE, 
QPACK_MAX_TABLE_CAPACITY and QPACK_BLOCKED_STREAMS onto that decoder. Those 
settings describe the client's decoder (RFC 9114 4.2.2, RFC 9204 5), so the 
client was picking our limits, e.g. raising QPACK_BLOCKED_STREAMS above the 0 
we advertise.
   2. `QPACK::_decode_header` counted only name and value length per field, 
without the 32 octets RFC 9114 4.2.2 adds, so even a configured limit did not 
bound the number of fields.
   3. With no bound on field count this is a pre-auth algorithmic-complexity 
DoS: one HEADERS frame of N one-byte indexed static field lines (`0xc5`, 
`cookie` with an empty value) attaches N same-name fields, and 
`MIMEHdr::field_attach` walks the duplicate chain on every attach, 
synchronously on the net thread before remap or any request header hook runs. 
Timed through `QPACK::decode` (Debug build, arm64 Mac): 10 KB block 176 ms, 20 
KB 627 ms, 40 KB 2.3 s, 80 KB 8.9 s. With a 4096 limit the same blocks are 
rejected in about 3 ms.
   4. The decoder now takes the configured limit, the peer's SETTINGS go to 
`local_qpack` (the encoder, which does not use them yet), and each field counts 
name + value + 32 the way HPACK already does (`ADDITIONAL_OCTETS`), so 4096 
allows at most 107 empty cookies. The accumulator is 64-bit so a large 
configured limit cannot wrap it.
   5. Behavior change: a client that ignores our SETTINGS and sends more than 
the configured size now fails decoding; 
`proxy.config.http3.max_field_section_size` can be raised. A decode failure is 
still not turned into a stream reset (the `QPACK_EVENT_DECODE_FAILED` case in 
`Http3HeaderVIOAdaptor` is a FIXME), so such a request waits for the inactivity 
timeout, as any malformed header block does today.
   
   Added a test_QPACK.cc case at the 107/108 field boundary that fails on the 
unpatched decoder; full -Werror build and all test_http3/test_qpack cases pass 
on an OpenSSL 3.5 native QUIC build. clang-tidy was not run locally.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to