https://github.com/jbgutierrez/path-parse/pull/10 From 72c38e3a36b8ed2ec03960ac659aa114cbe6a420 Mon Sep 17 00:00:00 2001 From: Jeffrey Pinyan Date: Thu, 13 May 2021 10:53:50 -0400 Subject: [PATCH 1/2] fixed regexes to avoid ReDoS attacks Signed-off-by: rpm-build --- deps/npm/node_modules/path-parse/index.js | 6 +++--- deps/npm/node_modules/path-parse/redos.js | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 deps/npm/node_modules/path-parse/redos.js diff --git a/deps/npm/node_modules/path-parse/index.js b/deps/npm/node_modules/path-parse/index.js index 3b7601f..e6b2af1 100644 --- a/deps/npm/node_modules/path-parse/index.js +++ b/deps/npm/node_modules/path-parse/index.js @@ -5,11 +5,11 @@ var isWindows = process.platform === 'win32'; // Regex to split a windows path into three parts: [*, device, slash, // tail] windows-only var splitDeviceRe = - /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; + /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?(.*)$/s; // Regex to split the tail part of the above into [*, dir, basename, ext] var splitTailRe = - /^([\s\S]*?)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/; + /^((?:[^\\\/]*[\\\/])*)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/; var win32 = {}; @@ -51,7 +51,7 @@ win32.parse = function(pathString) { // Split a filename into [root, dir, basename, ext], unix version // 'root' is just a slash, or nothing. var splitPathRe = - /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; + /^(\/?|)((?:[^\/]*\/)*)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; var posix = {}; diff --git a/deps/npm/node_modules/path-parse/redos.js b/deps/npm/node_modules/path-parse/redos.js new file mode 100644 index 0000000..261947f --- /dev/null +++ b/deps/npm/node_modules/path-parse/redos.js @@ -0,0 +1,20 @@ +var pathParse = require('.'); + +function build_attack(n) { + var ret = "" + for (var i = 0; i < n; i++) { + ret += "/" + } + return ret + "◎"; +} + +for(var i = 1; i <= 5000000; i++) { + if (i % 10000 == 0) { + var time = Date.now(); + var attack_str = build_attack(i) + pathParse.posix(attack_str); + pathParse.win32(attack_str); + var time_cost = Date.now() - time; + console.log("attack_str.length: " + attack_str.length + ": " + time_cost+" ms") + } +} -- 2.31.1 From 44d1c9cd047988bb819707c726d9640f8aabe04d Mon Sep 17 00:00:00 2001 From: Jeffrey Pinyan Date: Thu, 13 May 2021 11:51:45 -0400 Subject: [PATCH 2/2] streamlined regexes, simplified parse() returns Signed-off-by: rpm-build --- deps/npm/node_modules/path-parse/index.js | 52 ++++++++--------------- 1 file changed, 17 insertions(+), 35 deletions(-) diff --git a/deps/npm/node_modules/path-parse/index.js b/deps/npm/node_modules/path-parse/index.js index e6b2af1..f062d0a 100644 --- a/deps/npm/node_modules/path-parse/index.js +++ b/deps/npm/node_modules/path-parse/index.js @@ -2,29 +2,14 @@ var isWindows = process.platform === 'win32'; -// Regex to split a windows path into three parts: [*, device, slash, -// tail] windows-only -var splitDeviceRe = - /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?(.*)$/s; - -// Regex to split the tail part of the above into [*, dir, basename, ext] -var splitTailRe = - /^((?:[^\\\/]*[\\\/])*)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/; +// Regex to split a windows path into into [dir, root, basename, name, ext] +var splitWindowsRe = + /^(((?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?[\\\/]?)(?:[^\\\/]*[\\\/])*)((\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))[\\\/]*$/; var win32 = {}; -// Function to split a filename into [root, dir, basename, ext] function win32SplitPath(filename) { - // Separate device+slash from tail - var result = splitDeviceRe.exec(filename), - device = (result[1] || '') + (result[2] || ''), - tail = result[3] || ''; - // Split the tail into dir, basename and extension - var result2 = splitTailRe.exec(tail), - dir = result2[1], - basename = result2[2], - ext = result2[3]; - return [device, dir, basename, ext]; + return splitWindowsRe.exec(filename).slice(1); } win32.parse = function(pathString) { @@ -34,24 +19,24 @@ win32.parse = function(pathString) { ); } var allParts = win32SplitPath(pathString); - if (!allParts || allParts.length !== 4) { + if (!allParts || allParts.length !== 5) { throw new TypeError("Invalid path '" + pathString + "'"); } return { - root: allParts[0], - dir: allParts[0] + allParts[1].slice(0, -1), + root: allParts[1], + dir: allParts[0] === allParts[1] ? allParts[0] : allParts[0].slice(0, -1), base: allParts[2], - ext: allParts[3], - name: allParts[2].slice(0, allParts[2].length - allParts[3].length) + ext: allParts[4], + name: allParts[3] }; }; -// Split a filename into [root, dir, basename, ext], unix version +// Split a filename into [dir, root, basename, name, ext], unix version // 'root' is just a slash, or nothing. var splitPathRe = - /^(\/?|)((?:[^\/]*\/)*)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; + /^((\/?)(?:[^\/]*\/)*)((\.{1,2}|[^\/]+?|)(\.[^.\/]*|))[\/]*$/; var posix = {}; @@ -67,19 +52,16 @@ posix.parse = function(pathString) { ); } var allParts = posixSplitPath(pathString); - if (!allParts || allParts.length !== 4) { + if (!allParts || allParts.length !== 5) { throw new TypeError("Invalid path '" + pathString + "'"); } - allParts[1] = allParts[1] || ''; - allParts[2] = allParts[2] || ''; - allParts[3] = allParts[3] || ''; - + return { - root: allParts[0], - dir: allParts[0] + allParts[1].slice(0, -1), + root: allParts[1], + dir: allParts[0].slice(0, -1), base: allParts[2], - ext: allParts[3], - name: allParts[2].slice(0, allParts[2].length - allParts[3].length) + ext: allParts[4], + name: allParts[3], }; }; -- 2.31.1