Skip to content

Harden HTTP/1.1 request framing parsing - #186

Merged
VolkerChristian merged 3 commits into
masterfrom
codex/harden-http/1.1-request-framing-and-parsing
Jul 11, 2026
Merged

Harden HTTP/1.1 request framing parsing#186
VolkerChristian merged 3 commits into
masterfrom
codex/harden-http/1.1-request-framing-and-parsing

Conversation

@VolkerChristian

Copy link
Copy Markdown
Member

Motivation

  • Eliminate ambiguous/substring header checks and deterministic framing ambiguities that enable parser desync or request-smuggling style edge cases.
  • Enforce simple, safe server-side framing rules for HTTP/1.1 requests (TE/CL/Host/chunked) without redesigning the public API.
  • Make chunked decoding and Content-Length handling strict and overflow-safe while keeping the codebase small and pragmatic.

Description

  • Add reusable header/token helpers and a strict Content-Length parser in httputils (splitCommaSeparatedTokens, tokenEquals, headerHasToken, parseContentLength) and expose them via src/web/http/http_utils.{h,cpp}.
  • Move parser decoder setup into helpers on Parser (useChunkedBodyDecoder, useIdentityBodyDecoder, configureTrailerDecoder) and use parseContentLength and token helpers in Parser::analyzeHeader to decide decoders instead of substring heuristics (src/web/http/Parser.{h,cpp}).
  • Harden server request parsing in RequestParser to: require HTTP/1.1 Host, reject Transfer-Encoding + Content-Length, parse Transfer-Encoding as exact comma-separated tokens and accept only a final chunked coding for requests, and use exact Connection token parsing (src/web/http/server/RequestParser.{cpp,h}).
  • Use exact token parsing for Connection in the client response parser (src/web/http/client/ResponseParser.cpp).
  • Allow empty header values at the generic Fields decoder level while keeping name/whitespace checks; move semantic empty-value checks to specific headers (Host, CL, TE) (src/web/http/decoder/Fields.cpp).
  • Tighten chunked decoder: parse the chunk-size token up to ; or CRLF, validate it is non-empty hex, detect overflow, ignore (but not accept) extensions safely, reject trailing garbage like 5xyz, and always transition to trailer parsing after the zero chunk while preventing trailers from overriding framing headers (src/web/http/decoder/Chunked.cpp, src/web/http/Parser.cpp).
  • Tests: extend tests/unit/http/HttpMessageParserTest.cpp with focused cases for Transfer-Encoding token rules, TE+CL rejection, Content-Length duplicates/list/invalid handling, Host enforcement, pipelined request behavior for bodiless requests, Connection token parsing, and several chunked edge cases.
  • Files changed (key): Parser.{h,cpp}, server/RequestParser.{h,cpp}, client/ResponseParser.cpp, decoder/Fields.cpp, decoder/Chunked.cpp, http_utils.{h,cpp}, tests/unit/http/HttpMessageParserTest.cpp.
  • Explicit confirmations in code: TE substring matching was removed in favor of exact token parsing; server-side TE+CL cases are rejected; HTTP/1.1 Host presence/validity is enforced; chunk-size trailing garbage is rejected; chunked trailers are parsed (empty or non-empty) and trailer fields are prevented from overwriting framing-sensitive headers; ordinary existing HTTP requests (GET with Host, POST with Content-Length, HTTP/1.0 behavior) remain supported.

Testing

  • Built unit tests and ran the new/updated HTTP parser tests locally: cmake -S . -B build -DSNODEC_BUILD_TESTS=ON then cmake --build build --target HttpMessageParserTest -j2 and ctest --test-dir build -R HttpMessageParserTest --output-on-failure (additional HTTP unit targets were built and exercised as noted below).
  • Also built and ran a set of HTTP unit targets: HttpRequestFormatterRawWireTest, HttpResponseFormatterRawWireTest, HttpMessageHeaderCasingTest, and HttpMessageTargetQueryEdgeTest and verified they pass.
  • Result: the added parser unit tests passed; the test invocation described above succeeded locally in the build environment.

Codex Task

@VolkerChristian
VolkerChristian merged commit 26913ab into master Jul 11, 2026
1 check passed
@VolkerChristian
VolkerChristian deleted the codex/harden-http/1.1-request-framing-and-parsing branch July 24, 2026 09:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant