-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
net/http: add MaxBytesHandler(h Handler, n int64) Handler #39567
Comments
We do have MaxHeaderBytes in http.Server already. |
Based on the discussion above, this seems like a likely accept. |
Ah sorry, I completely missed the comment from two weeks ago
Yep, that is the meat of the proposal. |
No change in consensus, so accepted. |
Change https://golang.org/cl/310529 mentions this issue: |
Sorry, I didn't see this proposal until now, so some late feedback which I also left on Gerrit:
The top comment on this issue touched on this ("a top level handler that wraps the http.Request.Body"), but I'm not sure others are aware that this is the first case of a Server tunable that's not really required. We cool with that? |
Doesn't a handler just need to call Another downside of the Server knob is that you can't control it per path so anyone that needs to do that will end up using the handler method. I also don't think the extra field on server adds much visibility to the problem if the common use case is ListenAndServe anyways. Additionally, any library that wants to do this still has to do the handler method as long as they support older versions of Go. |
No worries, I probably should've tagged a few HTTP folks initially. The original rationale for this proposal was that one of the most common HTTP related security issues we see in internet facing servers is people either not limiting the request body size at all, or limiting request body size inconsistently. Part of fixing this problem is more strongly documenting the security issues of not limiting body size, but another is making fixing the problem as frictionless as possible for the user (one thing I've heard repeatedly is "if it's important that I do this, why isn't it enabled by default"). I agree this breaks precedent, and I don't really love it, but I think it's the least terrible, and probably most usable, solution to the issue. Another considered solution was to add a
I think this is a reasonable issue, which has similar considerations as the existing |
I like the idea of a Handler wrapper func: it would fit nicely beside |
cc @fraenkel |
It's easy to make this work for http. I am trying to figure out how this would work for http/2 since it doesn't have all the necessary plumbing. |
@fraenkel, per discussion above, this can all be done with an http.Handler wrapper. The http2 package doesn't need to be aware of this: we can just hand it a Handler that does the right thing. |
I get that. However the entire body is sent and queued up in the pipe. The http case will add a connection close header. |
Can this issue be renamed "net/http: add MaxByteHandler(h Handler, n int64) Handler"? ISTM, that's the consensus. Happy to open a CL for that if it is. |
It'd be beneficial to do #30715 too. Having the error defined for this case ensures that users can easily check the error returned from e.g. |
Yes, they work well as a pair. |
Change https://golang.org/cl/346569 mentions this issue: |
Using ioutil.ReadAll on http.Request.Body is a rather common pattern (and one which is in fact used in at least one of the net/http examples) which can be somewhat dangerous as it can cause unbounded reads, leading to memory exhaustion and/or other funky behavior down the line when operating on the read contents (i.e. causing a stack overflow in encoding/json with massively nested structures being unmarshalled into an interface{}, see #31789).
The common solution to this problem is using http.MaxBytesReader (or less ideally ioutil.LimitedReader) either in a top level handler that wraps the http.Request.Body io.ReadCloser on all incoming requests (which is a bit boilerplate-y), or on each handler where you plan to read the request body (which is also quite verbose, and easy to forget to do leading to a vulnerable endpoint).
Ideally you would be able to set a field on http.Server, which when non-zero would automatically replace the request body reader with a MaxBytesReader on all incoming requests, preventing the user from having to either implement a top level handler, or a per handler reader replacement.
The text was updated successfully, but these errors were encountered: