Skip to content

Commit d3f1155

Browse files
committed
Added extra header validation by checking size incrementally during processing
1 parent b652fa5 commit d3f1155

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

lib/net/http/header.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,19 @@
181181
module Net::HTTPHeader
182182
MAX_KEY_LENGTH = 1024
183183
MAX_FIELD_LENGTH = 65536
184+
MAX_HEADER_LENGTH = 1024 * 1024 # 1 MiB
184185

185186
def initialize_http_header(initheader) #:nodoc:
186187
@header = {}
187188
return unless initheader
189+
190+
total_header_size = 0
188191
initheader.each do |key, value|
192+
total_header_size += (key.to_s.bytesize + (value ? value.to_s.bytesize : 0))
193+
if total_header_size > MAX_HEADER_LENGTH
194+
raise ArgumentError, "headers too large (#{total_header_size} bytes exceeds #{MAX_HEADER_LENGTH} bytes limit)"
195+
end
196+
189197
warn "net/http: duplicated HTTP header: #{key}", uplevel: 3 if key?(key) and $VERBOSE
190198
if value.nil?
191199
warn "net/http: nil HTTP header: #{key}", uplevel: 3 if $VERBOSE

test/net/http/test_httpheader.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,20 @@ def test_initialize_with_symbol
4040
assert_equal "abc", @c["foo"]
4141
end
4242

43+
def test_initialize_with_max_header_length_exceeded
44+
field_value = 'x' * (Net::HTTPHeader::MAX_FIELD_LENGTH - 100)
45+
num_headers = (Net::HTTPHeader::MAX_HEADER_LENGTH / Net::HTTPHeader::MAX_FIELD_LENGTH) + 2
46+
47+
large_headers = {}
48+
num_headers.times do |i|
49+
large_headers["Header#{i}"] = field_value
50+
end
51+
52+
assert_raise(ArgumentError) do
53+
@c.initialize_http_header(large_headers)
54+
end
55+
end
56+
4357
def test_size
4458
assert_equal 0, @c.size
4559
@c['a'] = 'a'

0 commit comments

Comments
 (0)