Skip to content

Commit

Permalink
Restrict broken mime parsing
Browse files Browse the repository at this point in the history
This commit restricts broken mime parsing to deal with a ReDOS
vulnerability.

[CVE-2022-30122]
  • Loading branch information
tenderlove committed May 26, 2022
1 parent 5280870 commit 41be3d7
Show file tree
Hide file tree
Showing 4 changed files with 5 additions and 18 deletions.
3 changes: 1 addition & 2 deletions lib/rack/multipart.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ module Multipart
TOKEN = /[^\s()<>,;:\\"\/\[\]?=]+/
CONDISP = /Content-Disposition:\s*#{TOKEN}\s*/i
VALUE = /"(?:\\"|[^"])*"|#{TOKEN}/
BROKEN_QUOTED = /^#{CONDISP}.*;\s*filename="(.*?)"(?:\s*$|\s*;\s*#{TOKEN}=)/i
BROKEN_UNQUOTED = /^#{CONDISP}.*;\s*filename=(#{TOKEN})/i
BROKEN = /^#{CONDISP}.*;\s*filename=(#{VALUE})/i
MULTIPART_CONTENT_TYPE = /Content-Type: (.*)#{EOL}/ni
MULTIPART_CONTENT_DISPOSITION = /Content-Disposition:.*;\s*name=(#{VALUE})/ni
MULTIPART_CONTENT_ID = /Content-ID:\s*([^#{EOL}]*)/ni
Expand Down
3 changes: 2 additions & 1 deletion lib/rack/multipart/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,9 @@ def get_filename(head)
elsif filename = params['filename*']
encoding, _, filename = filename.split("'", 3)
end
when BROKEN_QUOTED, BROKEN_UNQUOTED
when BROKEN
filename = $1
filename = $1 if filename =~ /^"(.*)"$/
end

return unless filename
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
--AaB03x
Content-Type: image/jpeg
Content-Disposition: attachment; name="files"; filename=""human" genome.jpeg"; modification-date="Wed, 12 Feb 1997 16:29:51 -0500";
Content-Disposition: attachment; name="files"; filename="\"human\" genome.jpeg"; modification-date="Wed, 12 Feb 1997 16:29:51 -0500";
Content-Description: a complete map of the human genome

contents
Expand Down
15 changes: 1 addition & 14 deletions test/spec_multipart.rb
Original file line number Diff line number Diff line change
Expand Up @@ -421,19 +421,6 @@ def initialize(*)
params["files"][:tempfile].read.must_equal "contents"
end

it "parse filename with unescaped quotes" do
env = Rack::MockRequest.env_for("/", multipart_fixture(:filename_with_unescaped_quotes))
params = Rack::Multipart.parse_multipart(env)
params["files"][:type].must_equal "application/octet-stream"
params["files"][:filename].must_equal "escape \"quotes"
params["files"][:head].must_equal "Content-Disposition: form-data; " +
"name=\"files\"; " +
"filename=\"escape \"quotes\"\r\n" +
"Content-Type: application/octet-stream\r\n"
params["files"][:name].must_equal "files"
params["files"][:tempfile].read.must_equal "contents"
end

it "parse filename with escaped quotes and modification param" do
env = Rack::MockRequest.env_for("/", multipart_fixture(:filename_with_escaped_quotes_and_modification_param))
params = Rack::Multipart.parse_multipart(env)
Expand All @@ -442,7 +429,7 @@ def initialize(*)
params["files"][:head].must_equal "Content-Type: image/jpeg\r\n" +
"Content-Disposition: attachment; " +
"name=\"files\"; " +
"filename=\"\"human\" genome.jpeg\"; " +
"filename=\"\\\"human\\\" genome.jpeg\"; " +
"modification-date=\"Wed, 12 Feb 1997 16:29:51 -0500\";\r\n" +
"Content-Description: a complete map of the human genome\r\n"
params["files"][:name].must_equal "files"
Expand Down

0 comments on commit 41be3d7

Please sign in to comment.