From e5a085afe6abfaea1d1a78f54c45af9ef43ca1f9 Mon Sep 17 00:00:00 2001 From: huntr-helper Date: Wed, 16 Sep 2020 15:24:00 +0100 Subject: [PATCH] Security Fix for Regular Expression Denial of Service (ReDoS) - huntr.dev (#8) * Added two dangerous URLs to the fixtures array. * WIP: ReDoS mitigation - Fixed catastrophic backtracking that was happening at the check for a basic auth sequence, i.e. http://username:pass@example.com, but there is another happening at the domain var at line 11. * WIP: ReDoS mitigation - current state of my update fixes the vuln, but breaks 4 tests. * Added opt for punycode validation. Also made some minor regex tweaks. Passing all of notmatch and only failing 2 of urlmatch. * Added punycode url fixtures. * Simplified regex since case is always ignored. * Abandoned my fix and implemented RE2 to replace the built-in regex engine. * Removed the punycode validation I added because one of the operators does not work with RE2. Co-authored-by: Ben Co-authored-by: Jamie Slome <55323451+JamieSlome@users.noreply.github.com> --- index.js | 4 +++- test/notmatch.js | 6 ++++-- test/urlmatch.js | 6 +++++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 31a981e..2ed86d3 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,6 @@ 'use strict'; +const RE2 = require("re2"); + module.exports = function (opts) { var exact = (opts && opts.exact !== undefined) ? opts.exact : true; @@ -14,5 +16,5 @@ module.exports = function (opts) { var path = '(?:[/?#][^\\s"]*)?'; var regex = '(?:' + protocol + '|www\\.)' + auth + '(?:localhost|' + ip + '|' + host + domain + tld + ')' + port + path; - return exact ? new RegExp('(?:^' + regex + '$)', 'i') : new RegExp(regex, 'ig'); + return exact ? new RE2('(?:^' + regex + '$)', 'i') : new RE2(regex, 'ig'); }; diff --git a/test/notmatch.js b/test/notmatch.js index 7791d73..c7b6895 100644 --- a/test/notmatch.js +++ b/test/notmatch.js @@ -34,12 +34,14 @@ const fixtures = [ 'http://foo.bar/ /', 'http://google\\.com', 'http://www(google.com', - 'http://www.example.xn--overly-long-punycode-test-string-test-tests-123-test-test123/', 'http://www=google.com', 'https://www.g.com/error\n/bleh/bleh', 'rdar://1234', '/foo.bar/', - '///www.foo.bar./' + '///www.foo.bar./', + 'http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321http://huntr.devtestvulnerability2312321.testvulnerability23', + 'http://asdf:asdf@huntr.devtestvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321.testvulnerability2312321', + 'http://www.example.xn--overly-long-punycode-test-string-test-tests-123-test-test123/' ]; for (const x of fixtures) { diff --git a/test/urlmatch.js b/test/urlmatch.js index 6496d38..4941ae0 100644 --- a/test/urlmatch.js +++ b/test/urlmatch.js @@ -11,7 +11,6 @@ const exactFixtures = [ 'http://a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.com', 'http://mw1.google.com/mw-earth-vectordb/kml-samples/gp/seattle/gigapxl/$[level]/r$[y]_c$[x].jpg', 'http://user:pass@example.com:123/one/two.three?q1=a1&q2=a2#body', - 'http://www.microsoft.xn--comindex-g03d.html.irongeek.com', 'http://✪df.ws/123', 'http://localhost/', 'http://userid:password@example.com:8080', @@ -60,6 +59,11 @@ const exactFixtures = [ 'http://➡.ws/䨹', 'www.google.com/unicorn', 'http://example.com.', + 'http://www.microsoft.xn--comindex-g03d.html.irongeek.com', + 'www.microsoft.xn--comindex-g03d.html.irongeek.com', + 'http://xn--addas-o4a.de/', + 'xn--aerlngus-j80d.com', + 'xn--sngaporeair-zzb.com' ]; const notExactFixtures = [