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
Handle GET
, HEAD
, and OPTIONS
correctly in ContentLengthLimit
#989
Conversation
/// `GET`, `HEAD`, and `OPTIONS` requests are reject if they have a `Content-Length` header, | ||
/// otherwise they're accepted without the body being checked. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What will hyper do to requests with one of these methods that do have a body? Could this create an additional attack surface in practice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hyper is fine with GET requests with bodies.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh but it stops reading after content-length bytes are reached, or doesn't read the body at all if there is no content-length?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there is a content-length it stops reading after the length, if there is no content-length (and no chunked encoding) it doesn't read the body and it appears empty to the user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The body is assumed to be empty if there is no Transfer-Encoding
or Content-Length
header. If there is a Content-Length
header, hyper
will stop reading once Content-Length
bytes have been read.
The one hole here that we may want to close: If a GET
, HEAD
, or OPTIONS
doesn't have a Content-Length
header, but does have a Transfer-Encoding
header, then this extractor should reject the request (same as if missing the Content-Length
header). That will prevent a body being smuggled into a GET/HEAD/OPTIONS request where we can't verify the length limit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll fix that!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@neoeinstein I believe 711cc3e should do it!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One typo change and a pattern-matching improvement.
Co-authored-by: Marcus Griep <marcus@griep.us>
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
GET
, HEAD
, and OPTIONS
correctly ContentLengthLimit
GET
, HEAD
, and OPTIONS
correctly in ContentLengthLimit
Motivation
ContentLengthLimit
is normally applied to a single handler as a regular extractor. However nothing prevents the user from doing.layer(from_extractor::<ContentLengthLimit<(),1024>>())
to limit the size of payloads to all handlers. This doesn't work though since browsers don't send acontent-length
header onGET
requests causingContentLengthLimit
to reject the request.Solution
Change
ContentLengthLimit
to acceptGET
,HEAD
, andOPTIONS
requests that don't have acontent-length
header.We discussed this a bit in Discord and landed on rejecting
GET
,HEAD
, andOPTIONS
requests that have acontent-length
.We also agreed on not changing the body to an empty body.
I'd categorize this as a bug fix but I could see some making the argument that its a breaking change. Let me know what you think.
cc @neoeinstein