In strict mode http_parser rejects header-value bytes that fail
IS_HEADER_CHAR (CTLs other than HTAB, DEL, NUL), but for general header
values most bytes never reached that check:
- s_header_value_start consumed the first byte without IS_HEADER_CHAR
- after the second byte, the h_general fast path memchr()ed straight to
CR/LF, skipping every byte in between
So "a\x15b" was rejected with HPE_INVALID_HEADER_TOKEN while "\x15",
"ab\x15" and "abc\x00def" were accepted, and the result for a given
request could change with how it was split across recv() calls. RFC 9110
section 5.5 requires a recipient to reject or replace NUL, and strict
mode already means to reject the other CTLs too.
Check the first byte in s_header_value_start, and replace the memchr()
fast path with the validating loop upstream adopted in
nodejs/http-parser#469 ("revert memchr() optimization"), which fixed the
fast-path half of this there. Lenient mode is unchanged.
Add two [security] tests to esp_http_server test_apps over a shared table
of valid (HTAB, SP, obs-text) and invalid (CTL, DEL, NUL at several
positions) values: a parser-level test that splits each request at every
offset and byte by byte, and an end-to-end test that expects 200/400.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Register QUERY in HTTP_METHOD_MAP and accept a leading 'Q' in the
request-line matcher so esp_http_server can parse safe, idempotent
queries with a body.
Document HTTP_QUERY on the server API and cover a bodied QUERY request
in the esp_http_server test app.