Skip to content

Commit ee60354

Browse files
committed
Require CRLF line endings in request line and headers
Disallow bare CR, LF, NUL in header and request lines. Tighten parsing of request lines to only allow single spaces, as specified in the RFCs. Forcing this RFC-compliant behavior breaks a lot of tests, so fix the tests to correctly use CRLF instead of LF for requests (other than the specific checks for handling of bad requests). Fixes #137
1 parent a27d7ed commit ee60354

File tree

4 files changed

+133
-32
lines changed

4 files changed

+133
-32
lines changed

lib/webrick/httprequest.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ def read_request_line(socket)
458458
end
459459

460460
@request_time = Time.now
461-
if /^(\S+)\s+(\S++)(?:\s+HTTP\/(\d+\.\d+))?\r?\n/mo =~ @request_line
461+
if /^(\S+) (\S++)(?: HTTP\/(\d+\.\d+))?\r\n/mo =~ @request_line
462462
@request_method = $1
463463
@unparsed_uri = $2
464464
@http_version = HTTPVersion.new($3 ? $3 : "0.9")
@@ -471,7 +471,7 @@ def read_request_line(socket)
471471
def read_header(socket)
472472
if socket
473473
while line = read_line(socket)
474-
break if /\A(#{CRLF}|#{LF})\z/om =~ line
474+
break if /\A#{CRLF}\z/om =~ line
475475
if (@request_bytes += line.bytesize) > MAX_HEADER_LENGTH
476476
raise HTTPStatus::RequestEntityTooLarge, 'headers too large'
477477
end

lib/webrick/httputils.rb

+6-4
Original file line numberDiff line numberDiff line change
@@ -173,16 +173,18 @@ def parse_header(raw)
173173
field = nil
174174
raw.each_line{|line|
175175
case line
176-
when /^([A-Za-z0-9!\#$%&'*+\-.^_`|~]+):(.*?)\z/om
177-
field, value = $1, $2.strip
176+
when /^([A-Za-z0-9!\#$%&'*+\-.^_`|~]+):([^\r\n\0]*?)\r\n\z/om
177+
field, value = $1, $2
178178
field.downcase!
179179
header[field] = HEADER_CLASSES[field].new unless header.has_key?(field)
180180
header[field] << value
181-
when /^\s+(.*?)/om
182-
value = line.strip
181+
when /^\s+([^\r\n\0]*?)\r\n/om
183182
unless field
184183
raise HTTPStatus::BadRequest, "bad header '#{line}'."
185184
end
185+
value = line
186+
value.lstrip!
187+
value.slice!(-2..-1)
186188
header[field][-1] << " " << value
187189
else
188190
raise HTTPStatus::BadRequest, "bad header '#{line}'."

test/webrick/test_filehandler.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def make_range_request(range_spec)
3333
Range: #{range_spec}
3434
3535
END_OF_REQUEST
36-
return StringIO.new(msg.gsub(/^ {6}/, ""))
36+
return StringIO.new(msg.gsub(/^ {6}/, "").gsub("\n", "\r\n"))
3737
end
3838

3939
def make_range_response(file, range_spec)

0 commit comments

Comments
 (0)