From d3f11556fec884a14e637b6e5841f447d2db7568 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Wed, 11 Jun 2025 11:40:27 +0900 Subject: [PATCH] Added extra header validation by checking size incrementally during processing --- lib/net/http/header.rb | 8 ++++++++ test/net/http/test_httpheader.rb | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/lib/net/http/header.rb b/lib/net/http/header.rb index 30c632cc..2022071b 100644 --- a/lib/net/http/header.rb +++ b/lib/net/http/header.rb @@ -181,11 +181,19 @@ module Net::HTTPHeader MAX_KEY_LENGTH = 1024 MAX_FIELD_LENGTH = 65536 + MAX_HEADER_LENGTH = 1024 * 1024 # 1 MiB def initialize_http_header(initheader) #:nodoc: @header = {} return unless initheader + + total_header_size = 0 initheader.each do |key, value| + total_header_size += (key.to_s.bytesize + (value ? value.to_s.bytesize : 0)) + if total_header_size > MAX_HEADER_LENGTH + raise ArgumentError, "headers too large (#{total_header_size} bytes exceeds #{MAX_HEADER_LENGTH} bytes limit)" + end + warn "net/http: duplicated HTTP header: #{key}", uplevel: 3 if key?(key) and $VERBOSE if value.nil? warn "net/http: nil HTTP header: #{key}", uplevel: 3 if $VERBOSE diff --git a/test/net/http/test_httpheader.rb b/test/net/http/test_httpheader.rb index 69563168..49d59710 100644 --- a/test/net/http/test_httpheader.rb +++ b/test/net/http/test_httpheader.rb @@ -40,6 +40,20 @@ def test_initialize_with_symbol assert_equal "abc", @c["foo"] end + def test_initialize_with_max_header_length_exceeded + field_value = 'x' * (Net::HTTPHeader::MAX_FIELD_LENGTH - 100) + num_headers = (Net::HTTPHeader::MAX_HEADER_LENGTH / Net::HTTPHeader::MAX_FIELD_LENGTH) + 2 + + large_headers = {} + num_headers.times do |i| + large_headers["Header#{i}"] = field_value + end + + assert_raise(ArgumentError) do + @c.initialize_http_header(large_headers) + end + end + def test_size assert_equal 0, @c.size @c['a'] = 'a'