Open ebenoist opened 5 years ago
I noticed the same thing when extracting a URL with a fragment (#
) part where the Template
does not include a fragment. Execution time seems to grow exponentially as the path length increases.
EDIT: I saw in CHANGELOG.md
that version 2.8.0 fixes a ReDoS vulnerability. However, this issue still occurs on 2.8.0.
Demonstration:
require 'addressable/template'
require 'benchmark'
template = Addressable::Template.new('http://www.example.com{/path*}')
(15..30).each do |path_length|
path = "a"*path_length
extract_time = Benchmark.realtime do
template.extract("http://www.example.com/#{path}#fragment")
end
puts "path length: #{path_length}, extract time: #{'%.2f' % extract_time}s"
end
output:
path length: 15, extract time: 0.01s
path length: 16, extract time: 0.01s
path length: 17, extract time: 0.02s
path length: 18, extract time: 0.03s
path length: 19, extract time: 0.07s
path length: 20, extract time: 0.13s
path length: 21, extract time: 0.26s
path length: 22, extract time: 0.52s
path length: 23, extract time: 1.03s
path length: 24, extract time: 2.07s
path length: 25, extract time: 4.15s
path length: 26, extract time: 8.34s
path length: 27, extract time: 16.49s
path length: 28, extract time: 33.17s
path length: 29, extract time: 75.10s
path length: 30, extract time: 142.61s
Yup, saw the CVE reported today and figured it was this issue. We've removed the need to pass untrusted URIs to this library, but I can also confirm that the issue still exists.
Template Used
When the template above extracts a url with an empty query string, the regex used displays immense performance degradation.
All the time spent (~12 seconds on a modern Macbook Pro) is spent attempting to match the uri with the generated expansion regex.
Bad Regex
Reproduction
Thank you @joshkrueger for helping isolate the issue.