-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Content-length validation does not handle spaces #3321
Comments
Can you say more about how exactly this happens? It's true that we don't strip the value when parsing content-length, but it's supposed to already be stripped in the last line of The Line 188 in a48d634
I do see a couple of potential issues in edge cases, though.
Both of these cases are errors now although they were accepted prior to bf90f3a. I think they're both technically legal although I'd have to go back to the RFCs to be sure. |
We had some code that was manually proxying headers from an upstream request to a response that was pushing all of the lines passed to a |
I just tested sending a request with a |
The Content-Length needs to be the last header which then gets interpreted as a multi-line continuation and then adds a space itself, as stated in the first message. |
Got it; now I can reproduce the bug. Agreed that this is a problem. Also, it turns out that gunicorn and fasthttp also have this exact same bug. |
I'm still not clear on what exactly the problem is. Is there an issue with I see that there's a design mismatch in the interfaces of header_callback and parse_line: the former gives you the newlines, while parse_line expects them to be removed (this isn't formally specified but it's implied by the doctest). So you can't actually pass the values from header_callback directly to parse_line, even though this is superficially a reasonable thing to do. There's also a couple of weird edge cases I noted at the bottom of #3321 (comment) Does that cover everything or am I missing something? Solutions to the design mismatch include:
|
Aha, now I see the problem. Single-line headers have leading and trailing whitespace stripped, while continuation lines make it possible to construct a header with trailing whitespace, potentially confusing users of that header. RFC 9110 is clear that trailing whitespace should be stripped from header values. I'm going to:
|
When I wrote this, you could pass headers from header_callback to parse_line and it would work in most cases (except involving continuation lines). But in #3387 I broke this accidental feature, and now (starting with Tornado 6.4.1) combining header_callback with parse_line adds trailing whitespace to every header unless you manually strip the trailing CRLF. So I think we need to fully handle trailing CRLF in parse_line and not just lines that are whitespace-only. |
Additional validation of Content-Length parsing was introduced in bf90f3a however, the value is not
strip
ed and therefore a value of'0 '
causes aValueError
.This is a particular issue because if
Content-Length
is the last header in a request andparse_line
is being called then the\r\n
of the end of the header is interpreted as a multi-line continuation and appends the space to the end inHTTPHeaders.parse_line
:new_part = " " + line.lstrip()
.@bdarnell
The text was updated successfully, but these errors were encountered: