reject transfer-encoding requests in finish_request#2654
Merged
stephenberry merged 2 commits intoJun 20, 2026
Conversation
Collaborator
|
I'd like to note that RFC 7230 doesn't have a section 6.3.3. The section you're talking about is 3.3.1 |
Contributor
Author
|
Good catch, that was a typo. It's 3.3.1, where the 501 for an unknown transfer coding lives. Fixed the code comment and the description. |
stephenberry
added a commit
that referenced
this pull request
Jun 20, 2026
…230 3.2.4) (#2661) A header line using obsolete line folding (obs-fold) or with whitespace between the field-name and the colon was parsed leniently and stored under a mangled key. That let an obfuscated Transfer-Encoding ("Transfer-Encoding : chunked", a tab before the colon, or a value carried on a folded continuation line) slip past the header lookups that frame the request body: the server saw no Transfer-Encoding/Content-Length, treated the body as empty, and left the encoded payload in the keep-alive buffer where it was reparsed as a second, smuggled request once a folding/whitespace-lenient front-end framed the body as chunked (TE/CL desync, request smuggling). try_parse_request now rejects both forms with 400 Bad Request and closes the connection, as RFC 7230 3.2.4 requires; closing discards the leftover bytes. Well-formed requests, including header values that contain spaces and colons, are unaffected. Complements #2654 (which rejects a clean Transfer-Encoding header); together they close the obfuscated and non-obfuscated TE/CL desync variants. Adds http_header_strictness_test covering the space-before-colon, tab-before- colon, and obs-fold smuggling vectors plus a well-formed positive control.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The server frames request bodies with Content-Length only and ignores Transfer-Encoding, since chunked request bodies are unsupported. finish_request reaches the Content-Length step with a request that carries Transfer-Encoding and no Content-Length, treats it as a zero-length body, and leaves the encoded payload sitting in the keep-alive buffer. A front-end proxy that does honor Transfer-Encoding forwards the whole thing as one request, so those leftover bytes get parsed here as a second request the client never sent (TE/CL desync, request smuggling).
Before: a Transfer-Encoding request was silently accepted with an empty body and the chunk data was reinterpreted as a pipelined request. After: finish_request answers 501 and closes the connection when a Transfer-Encoding header is present, which RFC 7230 3.3.1 calls for on an encoding the server cannot decode. The check sits next to the Content-Length parsing because that is the layer that frames the body and decides what stays in the buffer; the tradeoff is that a (currently unsupported) chunked client now gets a hard 501 instead of a confusing empty-body 200. Content-Length requests are unaffected.