From a115427168367909b95474e7173cdc5088ec6149 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Tue, 15 Aug 2023 14:37:59 -0700 Subject: [PATCH] Raise HTTPStatus::BadRequest for requests with invalid/duplicate content-length headers Addresses CVE-2023-40225. Fixes #119 --- lib/webrick/httprequest.rb | 8 ++++++++ test/webrick/test_httprequest.rb | 25 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/lib/webrick/httprequest.rb b/lib/webrick/httprequest.rb index 680ac65..7a1686b 100644 --- a/lib/webrick/httprequest.rb +++ b/lib/webrick/httprequest.rb @@ -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") diff --git a/test/webrick/test_httprequest.rb b/test/webrick/test_httprequest.rb index 2ff08d6..9033217 100644 --- a/test/webrick/test_httprequest.rb +++ b/test/webrick/test_httprequest.rb @@ -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