-
Notifications
You must be signed in to change notification settings - Fork 183
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
fix: prevent HEAD
requests from writing body in streamhandler
#1113
base: master
Are you sure you want to change the base?
Conversation
HEAD
requests from writing body in streamhandler
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #1113 +/- ##
==========================================
+ Coverage 82.70% 82.71% +0.01%
==========================================
Files 32 32
Lines 3053 3055 +2
==========================================
+ Hits 2525 2527 +2
Misses 528 528 ☔ View full report in Codecov by Sentry. |
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.
Hmmmm, yeah, this seems fine. I tried seeing if there was somewhere else we could enforce this (like startwrite or unsafe_write for Stream), but I think this fine. Mind adding a quick test and then we can merge?
@quinnj why did you dismiss this idea? Seems like we could bail early in Line 85 in a2ce750
n = 0 ? This would take care of both request handler and stream handler, I think?
|
@testset "HEAD request without body" begin | ||
sometext = "This is a big body that we don't want returned during a head" | ||
handler = req -> begin | ||
return HTTP.Response(200, [], sometext) | ||
end | ||
server = HTTP.serve!(handler; listenany=true) | ||
port = HTTP.port(server) | ||
|
||
response = HTTP.head("http://localhost:$port") | ||
@test response.status == 200 | ||
@test String(response.body) == "" | ||
|
||
response = HTTP.get("http://localhost:$port") | ||
@test response.status == 200 | ||
@test String(response.body) == sometext | ||
|
||
close(server) | ||
end |
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 very interesting thing here is that this fails with
HEAD request without body: Error During Test at /home/pgeorgakopoulos/pluto/HTTP.jl/test/server.jl:316
Got exception outside of a @test
HTTP.RequestError:
HTTP.Request:
HTTP.Messages.Request:
"""
GET / HTTP/1.1
Host: localhost:8081
Accept: */*
User-Agent: HTTP.jl/1.10.0-rc1
Content-Length: 0
Accept-Encoding: gzip
"""Underlying error:
HTTP.Parsers.ParseError(:INVALID_STATUS_LINE, "2e\r")
...
caused by: TaskFailedException
nested task error: HTTP.Parsers.ParseError(:INVALID_STATUS_LINE, "2e\r")
...
caused by: HTTP.Parsers.ParseError(:INVALID_STATUS_LINE, "This is a big body that we don't want returnedHTTP/1.1 200 OK\r")
Stacktrace:
[1] parse_status_line!(bytes::String, response::HTTP.Messages.Response)
@ HTTP.Parsers ~/pluto/HTTP.jl/src/Parsers.jl:206
without this PR
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.
which is very similar to a request smuggling attack.
|
(Note: if you're using your own
streamhandler
, you're on your own)fixes: #1112
with this fix, 3 connections fly over the same connection with cURL