From 8e8869d625e73e16b576b6d31b50208e9ec8002f Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Thu, 8 Dec 2022 15:54:28 -0800 Subject: Limit all multipart parts, not just files Previously we would limit the number of multipart parts which were files, but not other parts. In some cases this could cause parsing of maliciously crafted inputs to take longer than expected. [CVE-2023-27530] --- test/spec_multipart.rb | 14 +++++++++++++- test/spec_request.rb | 18 +++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/spec_multipart.rb b/test/spec_multipart.rb index 14d0f6a5..48d03e43 100644 --- a/test/spec_multipart.rb +++ b/test/spec_multipart.rb @@ -696,7 +696,7 @@ content-type: image/jpeg\r end end - it "reach a multipart limit" do + it "reach a multipart file limit" do begin previous_limit = Rack::Utils.multipart_part_limit Rack::Utils.multipart_part_limit = 3 @@ -708,6 +708,18 @@ content-type: image/jpeg\r end end + it "reach a multipart total limit" do + begin + previous_limit = Rack::Utils.multipart_total_part_limit + Rack::Utils.multipart_total_part_limit = 5 + + env = Rack::MockRequest.env_for '/', multipart_fixture(:three_files_three_fields) + lambda { Rack::Multipart.parse_multipart(env) }.must_raise Rack::Multipart::MultipartTotalPartLimitError + ensure + Rack::Utils.multipart_total_part_limit = previous_limit + end + end + it "return nil if no UploadedFiles were used" do data = Rack::Multipart.build_multipart("people" => [{ "submit-name" => "Larry", "files" => "contents" }]) data.must_be_nil diff --git a/test/spec_request.rb b/test/spec_request.rb index f4e940ce..9a94b35f 100644 --- a/test/spec_request.rb +++ b/test/spec_request.rb @@ -1352,7 +1352,7 @@ EOF f[:tempfile].size.must_equal 76 end - it "MultipartPartLimitError when request has too many multipart parts if limit set" do + it "MultipartPartLimitError when request has too many multipart file parts if limit set" do begin data = 10000.times.map { "--AaB03x\r\ncontent-type: text/plain\r\ncontent-disposition: attachment; name=#{SecureRandom.hex(10)}; filename=#{SecureRandom.hex(10)}\r\n\r\ncontents\r\n" }.join("\r\n") data += "--AaB03x--\r" @@ -1368,6 +1368,22 @@ EOF end end + it "MultipartPartLimitError when request has too many multipart total parts if limit set" do + begin + data = 10000.times.map { "--AaB03x\r\ncontent-type: text/plain\r\ncontent-disposition: attachment; name=#{SecureRandom.hex(10)}\r\n\r\ncontents\r\n" }.join("\r\n") + data += "--AaB03x--\r" + + options = { + "CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x", + "CONTENT_LENGTH" => data.length.to_s, + :input => StringIO.new(data) + } + + request = make_request Rack::MockRequest.env_for("/", options) + lambda { request.POST }.must_raise Rack::Multipart::MultipartTotalPartLimitError + end + end + it 'closes tempfiles it created in the case of too many created' do begin data = 10000.times.map { "--AaB03x\r\ncontent-type: text/plain\r\ncontent-disposition: attachment; name=#{SecureRandom.hex(10)}; filename=#{SecureRandom.hex(10)}\r\n\r\ncontents\r\n" }.join("\r\n") -- cgit v1.2.1