From ffff364d8154af8d0abeafce9ebe4b5c4eade11c Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Tue, 17 Jan 2023 16:33:47 -0800 Subject: Make RFC2183 work with Ruby 3.2's caching Regexp (#2014) Ruby 3.2 includes a cache-based regexp optimization, which is detailed in https://bugs.ruby-lang.org/issues/19104. Which can speed up the regex engine on many cases which would previously have resulted in a ReDoS. One caveat of the implmentation is (quoting the issue): > A bounded or fixed times repetition nesting in another repetition > (e.g. /(a{2,3})*/). It is an implementation issue entirely, but we > believe it is hard to support this case correctly. Because of that limitation the RFC2183 regex was not previously able to use that optimization and was not able to mitigate two recent ReDoS CVEs. This commit manually expands a `{2}` fixed repetition, which allows Ruby 3.2's optimization to take effect. Before: > Regexp.linear_time?(/([0-9]{2})*/) => false > Regexp.linear_time?(Rack::Multipart::RFC2183) => false After: > Regexp.linear_time?(/([0-9][0-9])*/) => true > Regexp.linear_time?(Rack::Multipart::RFC2183) => true I want to make this change as additional hardening against possible ReDoS attacks in this regex. At the moment I don't know of any which are unpatched. --- lib/rack/multipart/parser.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/rack/multipart/parser.rb b/lib/rack/multipart/parser.rb index d5a3c8dd..ceafbc6b 100644 --- a/lib/rack/multipart/parser.rb +++ b/lib/rack/multipart/parser.rb @@ -32,7 +32,7 @@ module Rack REGULAR_PARAMETER_NAME = /#{ATTRIBUTE}#{SECTION}?/ REGULAR_PARAMETER = /(#{REGULAR_PARAMETER_NAME})=(#{VALUE})/ EXTENDED_OTHER_NAME = /#{ATTRIBUTE}\*[1-9][0-9]*\*/ - EXTENDED_OTHER_VALUE = /%[0-9a-fA-F]{2}|#{ATTRIBUTE_CHAR}/ + EXTENDED_OTHER_VALUE = /%[0-9a-fA-F][0-9a-fA-F]|#{ATTRIBUTE_CHAR}/ EXTENDED_OTHER_PARAMETER = /(#{EXTENDED_OTHER_NAME})=(#{EXTENDED_OTHER_VALUE}*)/ EXTENDED_INITIAL_NAME = /#{ATTRIBUTE}(?:\*0)?\*/ EXTENDED_INITIAL_VALUE = /[a-zA-Z0-9\-]*'[a-zA-Z0-9\-]*'#{EXTENDED_OTHER_VALUE}*/ -- cgit v1.2.1