mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
webrick/httprequest: limit request headers size
We use the same 112 KB limit started (AFAIK) by Mongrel, Thin, and Puma to prevent malicious users from using up all the memory with a single request. This also limits the damage done by excessive ranges in multipart Range: requests. Due to the way we rely on IO#gets and the desire to keep the code simple, the actual maximum header may be 4093 bytes larger than 112 KB, but we're splitting hairs at that point. * lib/webrick/httprequest.rb: define MAX_HEADER_LENGTH (read_header): raise when headers exceed max length git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62960 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
4639ac8953
commit
7e1f2a5aa9
2 changed files with 25 additions and 1 deletions
|
@ -414,9 +414,13 @@ module WEBrick
|
||||||
|
|
||||||
MAX_URI_LENGTH = 2083 # :nodoc:
|
MAX_URI_LENGTH = 2083 # :nodoc:
|
||||||
|
|
||||||
|
# same as Mongrel, Thin and Puma
|
||||||
|
MAX_HEADER_LENGTH = (112 * 1024) # :nodoc:
|
||||||
|
|
||||||
def read_request_line(socket)
|
def read_request_line(socket)
|
||||||
@request_line = read_line(socket, MAX_URI_LENGTH) if socket
|
@request_line = read_line(socket, MAX_URI_LENGTH) if socket
|
||||||
if @request_line.bytesize >= MAX_URI_LENGTH and @request_line[-1, 1] != LF
|
@request_bytes = @request_line.bytesize
|
||||||
|
if @request_bytes >= MAX_URI_LENGTH and @request_line[-1, 1] != LF
|
||||||
raise HTTPStatus::RequestURITooLarge
|
raise HTTPStatus::RequestURITooLarge
|
||||||
end
|
end
|
||||||
@request_time = Time.now
|
@request_time = Time.now
|
||||||
|
@ -435,6 +439,9 @@ module WEBrick
|
||||||
if socket
|
if socket
|
||||||
while line = read_line(socket)
|
while line = read_line(socket)
|
||||||
break if /\A(#{CRLF}|#{LF})\z/om =~ line
|
break if /\A(#{CRLF}|#{LF})\z/om =~ line
|
||||||
|
if (@request_bytes += line.bytesize) > MAX_HEADER_LENGTH
|
||||||
|
raise HTTPStatus::RequestEntityTooLarge, 'headers too large'
|
||||||
|
end
|
||||||
@raw_header << line
|
@raw_header << line
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -441,4 +441,21 @@ class TestWEBrickHTTPServer < Test::Unit::TestCase
|
||||||
s&.shutdown
|
s&.shutdown
|
||||||
th&.join
|
th&.join
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_gigantic_request_header
|
||||||
|
log_tester = lambda {|log, access_log|
|
||||||
|
assert_equal 1, log.size
|
||||||
|
assert log[0].include?('ERROR headers too large')
|
||||||
|
}
|
||||||
|
TestWEBrick.start_httpserver({}, log_tester){|server, addr, port, log|
|
||||||
|
server.mount('/', WEBrick::HTTPServlet::FileHandler, __FILE__)
|
||||||
|
TCPSocket.open(addr, port) do |c|
|
||||||
|
c.write("GET / HTTP/1.0\r\n")
|
||||||
|
junk = -"X-Junk: #{' ' * 1024}\r\n"
|
||||||
|
assert_raise(Errno::ECONNRESET, Errno::EPIPE) do
|
||||||
|
loop { c.write(junk) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue