Skip to content

Commit

Permalink
Prevent request smuggling
Browse files Browse the repository at this point in the history
If a request has both a content-length and transfer-encoding
headers, return a 400 response.  This is allowed by RFC 7230
section 3.3.3.3.

Fixes #145
  • Loading branch information
jeremyevans committed Sep 18, 2024
1 parent 0c600e1 commit d88321d
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 0 deletions.
4 changes: 4 additions & 0 deletions lib/webrick/httprequest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,10 @@ def parse_host_request_line(host)
def read_body(socket, block)
return unless socket
if tc = self['transfer-encoding']
if self['content-length']
raise HTTPStatus::BadRequest, "request with both transfer-encoding and content-length, possible request smuggling"
end

case tc
when /\Achunked\z/io then read_chunked(socket, block)
else raise HTTPStatus::NotImplemented, "Transfer-Encoding: #{tc}."
Expand Down
18 changes: 18 additions & 0 deletions test/webrick/test_httprequest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,24 @@ def test_duplicate_content_length_header
}
end

def test_content_length_and_transfer_encoding_headers_smuggling
msg = <<~HTTP.gsub("\n", "\r\n")
POST /user HTTP/1.1
Content-Length: 28
Transfer-Encoding: chunked
0
GET /admin HTTP/1.1
HTTP
req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
req.parse(StringIO.new(msg))
assert_raise(WEBrick::HTTPStatus::BadRequest){
req.body
}
end

def test_parse_headers
msg = <<~HTTP.gsub("\n", "\r\n")
GET /path HTTP/1.1
Expand Down

0 comments on commit d88321d

Please sign in to comment.