Skip to content

Commit f5faca9

Browse files
committed
Prevent request smuggling
If a request has both a content-length and transfer-encoding headers, return a 400 response. This is allowed by RFC 7230 section 3.3.3.3. Fixes #145
1 parent 0c600e1 commit f5faca9

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

lib/webrick/httprequest.rb

+4
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,10 @@ def parse_host_request_line(host)
531531
def read_body(socket, block)
532532
return unless socket
533533
if tc = self['transfer-encoding']
534+
if self['content-length']
535+
raise HTTPStatus::BadRequest, "request with both transfer-encoding and content-length, possible request smuggling"
536+
end
537+
534538
case tc
535539
when /\Achunked\z/io then read_chunked(socket, block)
536540
else raise HTTPStatus::NotImplemented, "Transfer-Encoding: #{tc}."

test/webrick/test_httprequest.rb

+18
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,24 @@ def test_duplicate_content_length_header
219219
}
220220
end
221221

222+
def test_content_length_and_transfer_encoding_headers_smuggling
223+
msg = <<~HTTP.gsub("\n", "\r\n")
224+
POST /user HTTP/1.1
225+
Content-Length: 28
226+
Transfer-Encoding: chunked
227+
228+
0
229+
230+
GET /admin HTTP/1.1
231+
232+
HTTP
233+
req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
234+
req.parse(StringIO.new(msg))
235+
assert_raise(WEBrick::HTTPStatus::BadRequest){
236+
req.body
237+
}
238+
end
239+
222240
def test_parse_headers
223241
msg = <<~HTTP.gsub("\n", "\r\n")
224242
GET /path HTTP/1.1

0 commit comments

Comments
 (0)