-
Notifications
You must be signed in to change notification settings - Fork 18k
net/http: Content-Length
values are not validated when Transfer-Encoding: chunked
is present
#65505
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
Comments
This discrepancy was found using the HTTP Garden. |
According to https://greenbytes.de/tech/webdav/rfc2616.html#rfc.section.4.4.p.5, if the message does include a non-identity transfer-coding, the Content-Length must be ignored. |
This is the expected behavior, please check out: Lines 630 to 666 in b8ac61e
|
RFC 9110 is clear that gateway servers must reject messages that contain an invalid
A gateway server that is implemented on top of net/http has no way of conforming to this rule. Caddy's reverse proxy violates the above rule for this reason. |
To be clear, I'm not saying that valid This is what nearly all other HTTP implementations do, including AIOHTTP, Apache httpd, Bun, cherrypy, daphne, Deno, fasthttp, Gunicorn, Hyper, Hypercorn, Jetty, Lighttpd, Mongoose, Nginx, Node.js, LiteSpeed, Passenger, Apache Tomcat, Tornado, OpenWrt uhttpd, Unicorn, Uvicorn, WEBrick, HAProxy, Pound, and Varnish. |
RFC 2616 is obsoleted by RFC 7230, which is itself obsoleted by RFC 9112. The current version of the text that you're referencing is this:
Note that it does not say to ignore the |
It is a bit confusing about the statements of |
In my opinion, an intermediary only removes the Content-Length header rather than checks the value of header is valid or not prior to remove it . |
After reading through the sections of I'll send a CL for this, but I need some comments from @neild on this before we submit it. |
Change https://go.dev/cl/561075 mentions this issue: |
I agree that the RFCs could be a little clearer about this, but I think the text really doesn't support your claim. From RFC 9110, section 8.6:
It's not clear from this text alone whether it's saying that the forwarded version of the message must not contain an invalid Content-Length header, or that messages containing invalid Content-Length headers must not be forwarded in any form. But the rest of the sentence clears up that ambiguity:
Given that they're making a point to explicitly say that normalization is acceptable when the Content-Length is a comma-separated list of equal values, this implies that normalization is not acceptable when the Content-Length is otherwise invalid. This is further supported by RFC 9112, section 6.3:
(emphasis mine) |
RFC 9112 Section 6.1 states:
This seems fairly explicit on the valid options when handling a request with both Content-Length and Transfer-Encoding: either reject it outright; or ignore Content-Length, process the message, and close the connection. |
On second thought, I think the current behavior is fine. I was misinterpreting the RFC. |
According to RFC 9110 and RFC 9112, invalid "Content-Length" headers might involve request smuggling or response splitting, which could also cause security failures. Currently, `net/http` ignores all "Content-Length" headers when there is a "Transfer-Encoding" header and forward the message anyway while other mainstream HTTP implementations such as Apache Tomcat, Nginx, HAProxy, Node.js, Deno, Tornado, etc. reject invalid Content-Length headers regardless of the presence of a "Transfer-Encoding" header and only forward chunked-encoding messages with either valid "Content-Length" headers or no "Content-Length" headers. Fixes #65505 Change-Id: I73af2ee0785137e56c7546a4cce4a5c5c348dbc5 Reviewed-on: https://go-review.googlesource.com/c/go/+/561075 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Bryan Mills <[email protected]> Reviewed-by: Damien Neil <[email protected]>
According to RFC 9110 and RFC 9112, invalid "Content-Length" headers might involve request smuggling or response splitting, which could also cause security failures. Currently, `net/http` ignores all "Content-Length" headers when there is a "Transfer-Encoding" header and forward the message anyway while other mainstream HTTP implementations such as Apache Tomcat, Nginx, HAProxy, Node.js, Deno, Tornado, etc. reject invalid Content-Length headers regardless of the presence of a "Transfer-Encoding" header and only forward chunked-encoding messages with either valid "Content-Length" headers or no "Content-Length" headers. Fixes golang#65505 Change-Id: I73af2ee0785137e56c7546a4cce4a5c5c348dbc5 Reviewed-on: https://go-review.googlesource.com/c/go/+/561075 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Bryan Mills <[email protected]> Reviewed-by: Damien Neil <[email protected]>
Go version
go version devel go1.23-b8ac61e6e6 Fri Feb 2 23:14:07 2024 +0000 linux/amd64
Output of
go env
in your module/workspace:What did you do?
Started a web server using net/http, and sent a request with an invalid
Content-Length
header, as well as aTransfer-Encoding: chunked
header. (e.g.GET / HTTP/1.1\r\nHost: a\r\nContent-Length: blahblahblah\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\n
)What did you see happen?
I received a 200 response, as though the invalid
Content-Length
value were not sent.What did you expect to see?
I expected to see a 400 response because the
Content-Length
value was invalid.The text was updated successfully, but these errors were encountered: