Skip to content

Commit

Permalink
Raise HTTPStatus::BadRequest for requests with invalid/duplicate cont…
Browse files Browse the repository at this point in the history
…ent-length headers

Addresses CVE-2023-40225.

Fixes ruby#119
  • Loading branch information
jeremyevans committed Aug 15, 2023
1 parent 649604e commit a115427
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
8 changes: 8 additions & 0 deletions lib/webrick/httprequest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,14 @@ def read_header(socket)
end
end
@header = HTTPUtils::parse_header(@raw_header.join)

if (content_length = @header['content-length']) && content_length.length != 0
if content_length.length > 1
raise HTTPStatus::BadRequest, "multiple content-length request headers"
elsif !/\A\d+\z/.match?(content_length[0])
raise HTTPStatus::BadRequest, "invalid content-length request header"
end
end
end

def parse_uri(str, scheme="http")
Expand Down
25 changes: 25 additions & 0 deletions test/webrick/test_httprequest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,31 @@ def test_request_uri_too_large
}
end

def test_invalid_content_length_header
['', ' ', ' +1', ' -1', ' a'].each do |cl|
msg = <<-_end_of_message_
GET / HTTP/1.1
Content-Length:#{cl}
_end_of_message_
req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
assert_raise(WEBrick::HTTPStatus::BadRequest){
req.parse(StringIO.new(msg.gsub(/^ {8}/, "")))
}
end
end

def test_duplicate_content_length_header
msg = <<-_end_of_message_
GET / HTTP/1.1
Content-Length: 1
Content-Length: 2
_end_of_message_
req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
assert_raise(WEBrick::HTTPStatus::BadRequest){
req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
}
end

def test_parse_headers
msg = <<-_end_of_message_
GET /path HTTP/1.1
Expand Down

0 comments on commit a115427

Please sign in to comment.