Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Some regular expressions are vulnerable to Regular Expression Denial of Service (ReDoS). While the regexes are quite inefficient in the worst case, this does not manifest as a DoS vulnerability in PHP because of the PHP regex backtracking defaults https://www.php.net/manual/en/pcre.configuration.php. If a regular expression takes too long to process, PHP just bails and says no match found even if the string would eventually match. However, in ports such as the ruby version which relies on these regular expressions, this manifests as a ReDoS vulnerability where a malicious visitor can send a crafted long user agent header and trigger denial of service. Let's take: Chrome/(\d+[\.\d]+).*MRCHROME This regular expression is vulnerable to ReDoS due to the section: (\d+[\.\d]+).*M \d+ matches digits [\.\d]+ matches digits (and '.') .* matches digits (and everything else) A malicious User-Agent string can be crafted containing 'Chrome/' followed by a long string of only digits: Chrome/000000000000000000000000000000000000000000000000000 but with 3000+ zeroes As this malicious string does NOT match the entire regular expression (no MRCHROME), the regular expression matcher will backtrack and try all N(N-1)/2 different ways of splitting the string of digits into the three \d groups. Due to this backtracking, the runtime of the malicious request will be approximately cubic with respect to N, so doubling the length of the string of digits will make processing take approximately 8 times longer. There are some remaining with quadratic ReDoS but that can be fixed another time if anybody cares. It requires much longer user-agent strings to trigger an actual effect. The fixed regexes are not 100% identical but I'm hoping that the test coverage is sufficient to make sure I've not messed up here.
- Loading branch information