Comparing version 2.0.2 to 2.1.0
@@ -5,20 +5,4 @@ # v2 | ||
### v2.0.2 | ||
## v2.0.0 | ||
1. Update regex-tree to address transitive dep DoS vector | ||
2. Update tape to address DoS vector | ||
Contributors: | ||
- [teppeis](https://github.com/teppeis) | ||
- [davisjam](https://github.com/davisjam) | ||
### v2.0.1 | ||
1. Fix parsing bug introduced during switch to regexp-tree. | ||
Contributors: | ||
- [davisjam](https://github.com/davisjam) | ||
### v2.0.0 | ||
1. Update README. | ||
@@ -25,0 +9,0 @@ 2. Switch AST library from ret to regexp-tree. |
91
index.js
@@ -1,22 +0,26 @@ | ||
const regexpTree = require('regexp-tree'); | ||
const analyzer = require('./lib/analyzer'); | ||
const analyzerFamily = require('./lib/analyzer-family'); | ||
module.exports = function (re, opts) { | ||
if (!opts) opts = {}; | ||
const replimit = opts.limit === undefined ? 25 : opts.limit; | ||
const DEFAULT_SAFE_REP_LIMIT = 25; | ||
const RET_IS_SAFE = true; | ||
const RET_IS_VULNERABLE = false; | ||
// Build an AST | ||
let myRegExp = null; | ||
let ast = null; | ||
class Args { | ||
constructor(regExp, analyzerOptions) { | ||
this.regExp = regExp; | ||
this.analyzerOptions = analyzerOptions; | ||
} | ||
} | ||
function safeRegex(re, opts) { | ||
try { | ||
// Construct a RegExp object | ||
if (re instanceof RegExp) { | ||
myRegExp = re; | ||
} else if (typeof re === 'string') { | ||
myRegExp = new RegExp(re); | ||
const args = buildArgs(re, opts); | ||
const analyzerResponses = askAnalyzersIfVulnerable(args); | ||
// Did any analyzer say true? | ||
if (analyzerResponses.find((isVulnerable) => isVulnerable)) { | ||
return RET_IS_VULNERABLE; | ||
} else { | ||
myRegExp = new RegExp(String(re)); | ||
return RET_IS_SAFE; | ||
} | ||
// Build an AST | ||
ast = regexpTree.parse(myRegExp); | ||
} catch (err) { | ||
@@ -26,26 +30,45 @@ // Invalid or unparseable input | ||
} | ||
} | ||
let currentStarHeight = 0; | ||
let maxObservedStarHeight = 0; | ||
function buildArgs(re, opts) { | ||
// Build AnalyzerOptions | ||
if (!opts) opts = {}; | ||
const heuristic_replimit = opts.limit === undefined ? DEFAULT_SAFE_REP_LIMIT : opts.limit; | ||
let repetitionCount = 0; | ||
const analyzerOptions = new analyzer.AnalyzerOptions(heuristic_replimit); | ||
regexpTree.traverse(ast, { | ||
'Repetition': { | ||
pre ({node}) { | ||
repetitionCount++; | ||
// Build RegExp | ||
let regExp = null; | ||
// Construct a RegExp object | ||
if (re instanceof RegExp) { | ||
regExp = re; | ||
} else if (typeof re === 'string') { | ||
regExp = new RegExp(re); | ||
} else { | ||
regExp = new RegExp(String(re)); | ||
} | ||
currentStarHeight++; | ||
if (maxObservedStarHeight < currentStarHeight) { | ||
maxObservedStarHeight = currentStarHeight; | ||
} | ||
}, | ||
return new Args(regExp, analyzerOptions); | ||
} | ||
post ({node}) { | ||
currentStarHeight--; | ||
} | ||
function askAnalyzersIfVulnerable(args) { | ||
let analyzerSaysVulnerable = []; | ||
// Query the Analyzers | ||
let Analyzer; | ||
for (Analyzer of analyzerFamily) { | ||
try { | ||
const analyzer = new Analyzer(args.analyzerOptions); | ||
analyzerSaysVulnerable.push(analyzer.isVulnerable(args.regExp)); | ||
} catch (err) { | ||
/* istanbul ignore next */ // No need to worry about code coverage here. | ||
analyzerSaysVulnerable.push(false); | ||
} | ||
}); | ||
} | ||
return (maxObservedStarHeight <= 1) && (repetitionCount <= replimit); | ||
}; | ||
return analyzerSaysVulnerable; | ||
} | ||
// Export | ||
module.exports = safeRegex; |
{ | ||
"name": "safe-regex", | ||
"version": "2.0.2", | ||
"version": "2.1.0", | ||
"description": "detect possibly catastrophic, exponential-time regular expressions", | ||
@@ -10,18 +10,29 @@ "main": "index.js", | ||
"devDependencies": { | ||
"tape": "^4.10.1" | ||
"jest": "^24.9.0" | ||
}, | ||
"scripts": { | ||
"test": "tape test/*.js" | ||
"test": "jest" | ||
}, | ||
"testling": { | ||
"files": "test/*.js", | ||
"browsers": [ | ||
"ie/8", | ||
"ie/9", | ||
"ie/10", | ||
"firefox/latest", | ||
"chrome/latest", | ||
"opera/latest", | ||
"safari/latest" | ||
] | ||
"jest": { | ||
"moduleFileExtensions": [ | ||
"js" | ||
], | ||
"testRegex": "test.*\\.spec\\.js$", | ||
"collectCoverage": true, | ||
"coverageReporters": [ | ||
"text-summary", | ||
"html", | ||
"lcov" | ||
], | ||
"collectCoverageFrom": [ | ||
"*.js" | ||
], | ||
"coverageThreshold": { | ||
"global": { | ||
"statements": 100, | ||
"branches": 100, | ||
"functions": 100, | ||
"lines": 100 | ||
} | ||
} | ||
}, | ||
@@ -28,0 +39,0 @@ "repository": { |
@@ -12,6 +12,4 @@ # safe-regex | ||
[![browser support](https://ci.testling.com/substack/safe-regex.png)](https://ci.testling.com/substack/safe-regex) | ||
[![Build Status](https://travis-ci.com/davisjam/safe-regex.svg?branch=master)](https://travis-ci.com/davisjam/safe-regex) | ||
[![build status](https://secure.travis-ci.org/substack/safe-regex.png)](http://travis-ci.org/substack/safe-regex) | ||
# Example | ||
@@ -62,4 +60,18 @@ | ||
# Versioning | ||
This project follows [Semantic Versioning 2.0 (semver)](https://semver.org/). | ||
Here are the project-specific meanings of MAJOR, MINOR, and PATCH updates: | ||
- MAJOR: "Incompatible" API changes were introduced. There are two types in this module: | ||
- Changes that modify the interface | ||
- Changes that cause any regexes to be marked as unsafe that were formerly marked as safe | ||
- MINOR: Functionality was added in a backwards-compatible manner. There are two types in this module: | ||
- Refactoring the analyses but not changing their results | ||
- Modifying the analyses to reduce false positives, without affecting negatives (false or true) | ||
- PATCH: I don't anticipate using PATCH for this module | ||
# License | ||
MIT | ||
[MIT](https://github.com/davisjam/safe-regex/blob/master/LICENSE) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
14937
12
350
75
1
1