eslint-plugin-security
Advanced tools
Comparing version 1.4.0 to 1.5.0
@@ -1,34 +0,65 @@ | ||
1.4.0 / 2017-06-12 | ||
================== | ||
* Add recommended ruleset to the usage example | ||
* Removes filenames from error output | ||
1.3.0 / 2017-02-09 | ||
================== | ||
# 1.4.0 / 2017-06-12 | ||
* README.md - document detect-disable-mustache-escape rule | ||
* README.md - documentation detect-new-buffer rule | ||
* Fixed crash with `detect-no-csrf-before-method-override` rule. | ||
* Style guide applied to all the code involving the tests | ||
* Removing a repeated test and style changes | ||
* ESLint added to the workflow | ||
* Removed not needed variables | ||
* Fix to a problem with a rule detected implementing the tests | ||
* Test engine with tests for all the rules | ||
* Add additional information to README for each rule | ||
- 1.4.0 | ||
- Stuff and things for 1.4.0 beep boop 🤖 | ||
- Merge pull request [#14](https://github.com/nodesecurity/eslint-plugin-security/issues/14) from travi/recommended-example | ||
Add recommended ruleset to the usage example | ||
- Merge pull request [#19](https://github.com/nodesecurity/eslint-plugin-security/issues/19) from pdehaan/add-changelog | ||
Add basic CHANGELOG.md file | ||
- Merge pull request [#17](https://github.com/nodesecurity/eslint-plugin-security/issues/17) from pdehaan/issue-16 | ||
Remove filename from error output | ||
- Add basic CHANGELOG.md file | ||
- Remove filename from error output | ||
- Add recommended ruleset to the usage example | ||
for [#9](https://github.com/nodesecurity/eslint-plugin-security/issues/9) | ||
- Merge pull request [#10](https://github.com/nodesecurity/eslint-plugin-security/issues/10) from pdehaan/issue-9 | ||
Add 'plugin:security/recommended' config to plugin | ||
- Merge pull request [#12](https://github.com/nodesecurity/eslint-plugin-security/issues/12) from tupaschoal/patch-1 | ||
Fix broken link for detect-object-injection | ||
- Fix broken link for detect-object-injection | ||
The current link leads to a 404 page, the new one is the proper page. | ||
- Add 'plugin:security/recommended' config to plugin | ||
1.2.0 / 2016-01-21 | ||
================== | ||
# 1.3.0 / 2017-02-09 | ||
* updated to check for new RegExp too | ||
- 1.3.0 | ||
- Merge branch 'scottnonnenberg-update-docs' | ||
- Fix merge conflicts because I can't figure out how to accept pr's in the right order | ||
- Merge pull request [#7](https://github.com/nodesecurity/eslint-plugin-security/issues/7) from HamletDRC/patch-1 | ||
README.md - documentation detect-new-buffer rule | ||
- Merge pull request [#8](https://github.com/nodesecurity/eslint-plugin-security/issues/8) from HamletDRC/patch-2 | ||
README.md - document detect-disable-mustache-escape rule | ||
- Merge pull request [#3](https://github.com/nodesecurity/eslint-plugin-security/issues/3) from jesusprubio/master | ||
A bit of love | ||
- README.md - document detect-disable-mustache-escape rule | ||
- README.md - documentation detect-new-buffer rule | ||
- Merge pull request [#6](https://github.com/nodesecurity/eslint-plugin-security/issues/6) from mathieumg/csrf-bug | ||
Fixed crash with `detect-no-csrf-before-method-override` rule | ||
- Fixed crash with `detect-no-csrf-before-method-override` rule. | ||
- Finishing last commit | ||
- Style guide applied to all the code involving the tests | ||
- Removing a repeated test and style changes | ||
- ESLint added to the workflow | ||
- Removed not needed variables | ||
- Fix to a problem with a rule detected implementing the tests | ||
- Test engine with tests for all the rules | ||
- Minor typos | ||
- A little bit of massage to readme intro | ||
- Add additional information to README for each rule | ||
1.1.0 / 2016-01-06 | ||
================== | ||
# 1.2.0 / 2016-01-21 | ||
* adding eslint rule to detect new buffer hotspot | ||
- 1.2.0 | ||
- updated to check for new RegExp too | ||
1.0.0 / 2015-11-15 | ||
================== | ||
# 1.1.0 / 2016-01-06 | ||
* rules disabled by default | ||
- 1.1.0 | ||
- adding eslint rule to detect new buffer hotspot | ||
# 1.0.0 / 2015-11-15 | ||
- updated desc | ||
- rules disabled by default | ||
- update links | ||
- beep boop |
@@ -40,5 +40,3 @@ /** | ||
recommended: { | ||
plugins: [ | ||
'security' | ||
], | ||
plugins: ['security'], | ||
rules: { | ||
@@ -45,0 +43,0 @@ 'security/detect-buffer-noassert': 'warn', |
{ | ||
"name": "eslint-plugin-security", | ||
"version": "1.4.0", | ||
"version": "1.5.0", | ||
"description": "Security rules for eslint", | ||
@@ -8,5 +8,8 @@ "main": "index.js", | ||
"changelog": "changelog eslint-plugin-security all > CHANGELOG.md", | ||
"test": "./node_modules/.bin/mocha test/**/*", | ||
"lint": "./node_modules/.bin/eslint .", | ||
"cont-int": "npm test && npm run-script lint" | ||
"release": "npx semantic-release", | ||
"test": "mocha test/**/*", | ||
"format": "prettier --write **/*.{md,js,yml}", | ||
"lint": "eslint .", | ||
"lint:fix": "eslint --fix .", | ||
"cont-int": "npm test && npm run lint" | ||
}, | ||
@@ -28,11 +31,27 @@ "repository": { | ||
"homepage": "https://github.com/nodesecurity/eslint-plugin-security#readme", | ||
"gitHooks": { | ||
"pre-commit": "lint-staged" | ||
}, | ||
"lint-staged": { | ||
"*.js": [ | ||
"prettier --write", | ||
"eslint --fix" | ||
], | ||
"*.md": "prettier --write", | ||
"*.yml": "prettier --write" | ||
}, | ||
"dependencies": { | ||
"safe-regex": "^1.1.0" | ||
"safe-regex": "^2.1.1" | ||
}, | ||
"devDependencies": { | ||
"changelog": "1.3.0", | ||
"eslint": "^2.10.1", | ||
"eslint": "^8.11.0", | ||
"eslint-config-nodesecurity": "^1.3.1", | ||
"mocha": "^2.4.5" | ||
"eslint-config-prettier": "^8.5.0", | ||
"lint-staged": "^12.3.7", | ||
"mocha": "^9.2.2", | ||
"prettier": "^2.6.2", | ||
"semantic-release": "^19.0.2", | ||
"yorkie": "^2.0.0" | ||
} | ||
} |
@@ -9,3 +9,3 @@ # eslint-plugin-security | ||
`npm install --save-dev eslint-plugin-security` | ||
`npm install --save-dev eslint-plugin-security` or `yarn add eslint-plugin-security --dev` | ||
@@ -17,5 +17,2 @@ ### Usage | ||
```js | ||
"plugins": [ | ||
"security" | ||
], | ||
"extends": [ | ||
@@ -26,3 +23,2 @@ "plugin:security/recommended" | ||
## Developer guide | ||
@@ -32,9 +28,11 @@ | ||
- Conventions: | ||
- We use our [custom ESLint setup](https://github.com/nodesecurity/eslint-config-nodesecurity). | ||
- Please implement a test for each new rule and use this command to be sure the new code respects the style guide and the tests keep passing: | ||
```sh | ||
npm run-script cont-int | ||
``` | ||
- We use our [custom ESLint setup](https://github.com/nodesecurity/eslint-config-nodesecurity). | ||
- Please implement a test for each new rule and use this command to be sure the new code respects the style guide and the tests keep passing: | ||
```sh | ||
npm run-script cont-int | ||
``` | ||
### Tests | ||
```sh | ||
@@ -50,7 +48,7 @@ npm test | ||
More information: https://blog.liftsecurity.io/2014/11/03/regular-expression-dos-and-node.js | ||
More information: [Regular Expression DoS and Node.js](docs/regular-expression-dos-and-node.md) | ||
#### `detect-buffer-noassert` | ||
Detects calls to [`buffer`](https://nodejs.org/api/buffer.html) with `noAssert` flag set | ||
Detect calls to [`buffer`](https://nodejs.org/api/buffer.html) with `noAssert` flag set. | ||
@@ -61,5 +59,5 @@ From the Node.js API docs: "Setting `noAssert` to true skips validation of the `offset`. This allows the `offset` to be beyond the end of the `Buffer`." | ||
Detects instances of [`child_process`](https://nodejs.org/api/child_process.html) & non-literal [`exec()`](https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback) | ||
Detect instances of [`child_process`](https://nodejs.org/api/child_process.html) & non-literal [`exec()`](https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback) | ||
More information: https://blog.liftsecurity.io/2014/08/19/Avoid-Command-Injection-Node.js | ||
More information: [Avoiding Command Injection in Node.js](docs/avoid-command-injection-node.md) | ||
@@ -70,9 +68,9 @@ #### `detect-disable-mustache-escape` | ||
More information: https://www.owasp.org/index.php/Cross-site_Scripting_(XSS) | ||
More information: [OWASP XSS](<https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)>) | ||
#### `detect-eval-with-expression` | ||
Detects `eval(variable)` which can allow an attacker to run arbitary code inside your process. | ||
Detects `eval(variable)` which can allow an attacker to run arbitrary code inside your process. | ||
More information: http://security.stackexchange.com/questions/94017/what-are-the-security-issues-with-eval-in-javascript | ||
More information: [What are the security issues with eval in JavaScript?](http://security.stackexchange.com/questions/94017/what-are-the-security-issues-with-eval-in-javascript) | ||
@@ -83,3 +81,3 @@ #### `detect-no-csrf-before-method-override` | ||
More information: https://blog.liftsecurity.io/2013/09/07/bypass-connect-csrf-protection-by-abusing | ||
More information: [Bypass Connect CSRF protection by abusing methodOverride Middleware](docs/bypass-connect-csrf-protection-by-abusing.md) | ||
@@ -90,3 +88,3 @@ #### `detect-non-literal-fs-filename` | ||
More information: https://www.owasp.org/index.php/Path_Traversal | ||
More information: [OWASP Path Traversal](https://www.owasp.org/index.php/Path_Traversal) | ||
@@ -97,3 +95,3 @@ #### `detect-non-literal-regexp` | ||
More information: https://blog.liftsecurity.io/2014/11/03/regular-expression-dos-and-node.js | ||
More information: [Regular Expression DoS and Node.js](docs/regular-expression-dos-and-node.md) | ||
@@ -104,3 +102,3 @@ #### `detect-non-literal-require` | ||
More information: http://www.bennadel.com/blog/2169-where-does-node-js-and-require-look-for-modules.htm | ||
More information: [Where does Node.js and require look for modules?](http://www.bennadel.com/blog/2169-where-does-node-js-and-require-look-for-modules.htm) | ||
@@ -111,3 +109,3 @@ #### `detect-object-injection` | ||
More information: https://blog.liftsecurity.io/2015/01/14/the-dangers-of-square-bracket-notation/ | ||
More information: [The Dangers of Square Bracket Notation](docs/the-dangers-of-square-bracket-notation.md) | ||
@@ -118,3 +116,3 @@ #### `detect-possible-timing-attacks` | ||
More information: https://snyk.io/blog/node-js-timing-attack-ccc-ctf/ | ||
More information: [A lesson in timing attacks](https://codahale.com/a-lesson-in-timing-attacks/) | ||
@@ -125,2 +123,6 @@ #### `detect-pseudoRandomBytes` | ||
More information: http://stackoverflow.com/questions/18130254/randombytes-vs-pseudorandombytes | ||
More information: [Randombytes vs pseudorandombytes](http://stackoverflow.com/questions/18130254/randombytes-vs-pseudorandombytes) | ||
#### `detect-new-buffer` | ||
Detect instances of new Buffer(argument) where argument is any non-literal value. |
{ | ||
"appendFile": [0], | ||
"appendFileSync": [0], | ||
"chmod": [0], | ||
"chmodSync": [0], | ||
"chown": [0], | ||
"chownSync": [0], | ||
"createReadStream": [0], | ||
"createWriteStream": [0], | ||
"exists": [0], | ||
"existsSync": [0], | ||
"lchmod": [0], | ||
"lchmodSync": [0], | ||
"lchown": [0], | ||
"lchownSync": [0], | ||
"link": [0,1], | ||
"linkSync": [0,1], | ||
"lstat": [0], | ||
"lstatSync": [0], | ||
"mkdir": [0], | ||
"mkdirSync": [0], | ||
"open": [0], | ||
"openSync": [0], | ||
"readdir": [0], | ||
"readdirSync": [0], | ||
"readFile": [0], | ||
"readFileSync": [0], | ||
"readlink": [0], | ||
"readlinkSync": [0], | ||
"realpath": [0], | ||
"realpathSync": [0], | ||
"rename": [0,1], | ||
"renameSync": [0,1], | ||
"rmdir": [0], | ||
"rmdirSync": [0], | ||
"stat": [0], | ||
"statSync": [0], | ||
"symlink": [0,1], | ||
"symlinkSync": [0,1], | ||
"truncate": [0], | ||
"truncateSync": [0], | ||
"unlink": [0], | ||
"unlinkSync": [0], | ||
"unwatchFile": [0], | ||
"utimes": [0], | ||
"utimesSync": [0], | ||
"watch": [0], | ||
"watchFile": [0], | ||
"writeFile": [0], | ||
"writeFileSync": [0] | ||
"appendFile": [0], | ||
"appendFileSync": [0], | ||
"chmod": [0], | ||
"chmodSync": [0], | ||
"chown": [0], | ||
"chownSync": [0], | ||
"createReadStream": [0], | ||
"createWriteStream": [0], | ||
"exists": [0], | ||
"existsSync": [0], | ||
"lchmod": [0], | ||
"lchmodSync": [0], | ||
"lchown": [0], | ||
"lchownSync": [0], | ||
"link": [0, 1], | ||
"linkSync": [0, 1], | ||
"lstat": [0], | ||
"lstatSync": [0], | ||
"mkdir": [0], | ||
"mkdirSync": [0], | ||
"open": [0], | ||
"openSync": [0], | ||
"readdir": [0], | ||
"readdirSync": [0], | ||
"readFile": [0], | ||
"readFileSync": [0], | ||
"readlink": [0], | ||
"readlinkSync": [0], | ||
"realpath": [0], | ||
"realpathSync": [0], | ||
"rename": [0, 1], | ||
"renameSync": [0, 1], | ||
"rmdir": [0], | ||
"rmdirSync": [0], | ||
"stat": [0], | ||
"statSync": [0], | ||
"symlink": [0, 1], | ||
"symlinkSync": [0, 1], | ||
"truncate": [0], | ||
"truncateSync": [0], | ||
"unlink": [0], | ||
"unlinkSync": [0], | ||
"unwatchFile": [0], | ||
"utimes": [0], | ||
"utimesSync": [0], | ||
"watch": [0], | ||
"watchFile": [0], | ||
"writeFile": [0], | ||
"writeFileSync": [0] | ||
} |
/** | ||
* Tries to detect buffer read / write calls that use noAssert set to true | ||
* @author Adam Baldwin | ||
* @author Adam Baldwin | ||
*/ | ||
//------------------------------------------------------------------------------ | ||
// Rule Definition | ||
//------------------------------------------------------------------------------ | ||
'use strict'; | ||
var names = []; | ||
//----------------------------------------------------------------------------- | ||
// Helpers | ||
//----------------------------------------------------------------------------- | ||
module.exports = function(context) { | ||
const read = [ | ||
'readUInt8', | ||
'readUInt16LE', | ||
'readUInt16BE', | ||
'readUInt32LE', | ||
'readUInt32BE', | ||
'readInt8', | ||
'readInt16LE', | ||
'readInt16BE', | ||
'readInt32LE', | ||
'readInt32BE', | ||
'readFloatLE', | ||
'readFloatBE', | ||
'readDoubleLE', | ||
'readDoubleBE', | ||
]; | ||
"use strict"; | ||
const write = [ | ||
'writeUInt8', | ||
'writeUInt16LE', | ||
'writeUInt16BE', | ||
'writeUInt32LE', | ||
'writeUInt32BE', | ||
'writeInt8', | ||
'writeInt16LE', | ||
'writeInt16BE', | ||
'writeInt32LE', | ||
'writeInt32BE', | ||
'writeFloatLE', | ||
'writeFloatBE', | ||
'writeDoubleLE', | ||
'writeDoubleBE', | ||
]; | ||
var read = [ | ||
"readUInt8", | ||
"readUInt16LE", | ||
"readUInt16BE", | ||
"readUInt32LE", | ||
"readUInt32BE", | ||
"readInt8", | ||
"readInt16LE", | ||
"readInt16BE", | ||
"readInt32LE", | ||
"readInt32BE", | ||
"readFloatLE", | ||
"readFloatBE", | ||
"readDoubleL", | ||
"readDoubleBE" | ||
]; | ||
//------------------------------------------------------------------------------ | ||
// Rule Definition | ||
//------------------------------------------------------------------------------ | ||
var write = [ | ||
"writeUInt8", | ||
"writeUInt16LE", | ||
"writeUInt16BE", | ||
"writeUInt32LE", | ||
"writeUInt32BE", | ||
"writeInt8", | ||
"writeInt16LE", | ||
"writeInt16BE", | ||
"writeInt32LE", | ||
"writeInt32BE", | ||
"writeFloatLE", | ||
"writeFloatBE", | ||
"writeDoubleLE", | ||
"writeDoubleBE" | ||
]; | ||
module.exports = { | ||
meta: { | ||
type: 'error', | ||
docs: { | ||
description: 'Detect calls to "buffer" with "noAssert" flag set.', | ||
category: 'Possible Security Vulnerability', | ||
recommended: true, | ||
url: 'https://github.com/nodesecurity/eslint-plugin-security#detect-buffer-noassert', | ||
}, | ||
__methodsToCheck: { | ||
read, | ||
write, | ||
}, | ||
}, | ||
create: function (context) { | ||
return { | ||
"MemberExpression": function (node) { | ||
var index; | ||
if (read.indexOf(node.property.name) !== -1) { | ||
index = 1; | ||
} else if (write.indexOf(node.property.name) !== -1) { | ||
index = 2; | ||
} | ||
MemberExpression: function (node) { | ||
let index; | ||
if (read.indexOf(node.property.name) !== -1) { | ||
index = 1; | ||
} else if (write.indexOf(node.property.name) !== -1) { | ||
index = 2; | ||
} | ||
if (index && node.parent && node.parent.arguments && node.parent.arguments[index] && node.parent.arguments[index].value) { | ||
var token = context.getTokens(node)[0]; | ||
return context.report(node, 'Found Buffer.' + node.property.name + ' with noAssert flag set true'); | ||
} | ||
if (index && node.parent && node.parent.arguments && node.parent.arguments[index] && node.parent.arguments[index].value) { | ||
return context.report(node, `Found Buffer.${node.property.name} with noAssert flag set true`); | ||
} | ||
}, | ||
}; | ||
}, | ||
}; | ||
@@ -6,2 +6,4 @@ /** | ||
'use strict'; | ||
//------------------------------------------------------------------------------ | ||
@@ -11,34 +13,41 @@ // Rule Definition | ||
var names = []; | ||
/* | ||
* Stores variable names pointing to child_process to check (child_process).exec() | ||
*/ | ||
const names = []; | ||
module.exports = function(context) { | ||
"use strict"; | ||
module.exports = { | ||
meta: { | ||
type: 'error', | ||
docs: { | ||
description: 'Detect instances of "child_process" & non-literal "exec()" calls.', | ||
category: 'Possible Security Vulnerability', | ||
recommended: true, | ||
url: 'https://github.com/nodesecurity/eslint-plugin-security/blob/main/docs/avoid-command-injection-node.md', | ||
}, | ||
}, | ||
create: function (context) { | ||
return { | ||
"CallExpression": function (node) { | ||
var token = context.getTokens(node)[0]; | ||
if (node.callee.name === 'require') { | ||
var args = node.arguments[0]; | ||
if (args && args.type === 'Literal' && args.value === 'child_process') { | ||
if (node.parent.type === 'VariableDeclarator') { | ||
names.push(node.parent.id.name); | ||
} else if (node.parent.type === 'AssignmentExpression' && node.parent.operator === '=') { | ||
names.push(node.parent.left.name); | ||
} | ||
return context.report(node, 'Found require("child_process")'); | ||
} | ||
CallExpression: function (node) { | ||
if (node.callee.name === 'require') { | ||
const args = node.arguments[0]; | ||
if (args && args.type === 'Literal' && args.value === 'child_process') { | ||
if (node.parent.type === 'VariableDeclarator') { | ||
names.push(node.parent.id.name); | ||
} else if (node.parent.type === 'AssignmentExpression' && node.parent.operator === '=') { | ||
names.push(node.parent.left.name); | ||
} | ||
}, | ||
"MemberExpression": function (node) { | ||
var token = context.getTokens(node)[0]; | ||
if (node.property.name === 'exec' && names.indexOf(node.object.name) > -1) { | ||
if (node.parent && node.parent.arguments && node.parent.arguments[0].type !== 'Literal') { | ||
return context.report(node, 'Found child_process.exec() with non Literal first argument'); | ||
} | ||
} | ||
return context.report(node, 'Found require("child_process")'); | ||
} | ||
} | ||
}, | ||
MemberExpression: function (node) { | ||
if (node.property.name === 'exec' && names.indexOf(node.object.name) > -1) { | ||
if (node.parent && node.parent.arguments.length && node.parent.arguments[0].type !== 'Literal') { | ||
return context.report(node, 'Found child_process.exec() with non Literal first argument'); | ||
} | ||
} | ||
}, | ||
}; | ||
}, | ||
}; |
@@ -1,18 +0,28 @@ | ||
module.exports = function(context) { | ||
'use strict'; | ||
"use strict"; | ||
module.exports = { | ||
meta: { | ||
type: 'error', | ||
docs: { | ||
description: 'Detects "object.escapeMarkup = false", which can be used with some template engines to disable escaping of HTML entities.', | ||
category: 'Possible Security Vulnerability', | ||
recommended: true, | ||
url: 'https://github.com/nodesecurity/eslint-plugin-security#detect-disable-mustache-escape' | ||
} | ||
}, | ||
create: function (context) { | ||
return { | ||
"AssignmentExpression": function(node) { | ||
if (node.operator === '=') { | ||
if (node.left.property) { | ||
if (node.left.property.name == 'escapeMarkup') { | ||
if (node.right.value == false) { | ||
context.report(node, 'Markup escaping disabled.') | ||
} | ||
} | ||
} | ||
AssignmentExpression: function (node) { | ||
if (node.operator === '=') { | ||
if (node.left.property) { | ||
if (node.left.property.name === 'escapeMarkup') { | ||
if (node.right.value === false) { | ||
context.report(node, 'Markup escaping disabled.'); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
} | ||
}; |
/** | ||
* Idnetifies eval with expression | ||
* Identifies eval with expression | ||
* @author Adam Baldwin | ||
*/ | ||
'use strict'; | ||
//------------------------------------------------------------------------------ | ||
@@ -10,13 +12,21 @@ // Rule Definition | ||
module.exports = function(context) { | ||
"use strict"; | ||
module.exports = { | ||
meta: { | ||
type: 'error', | ||
docs: { | ||
description: 'Detects "eval(variable)" which can allow an attacker to run arbitrary code inside your process.', | ||
category: 'Possible Security Vulnerability', | ||
recommended: true, | ||
url: 'https://github.com/nodesecurity/eslint-plugin-security#detect-eval-with-expression' | ||
} | ||
}, | ||
create: function (context) { | ||
return { | ||
"CallExpression": function(node) { | ||
if (node.callee.name === "eval" && node.arguments[0].type !== 'Literal') { | ||
context.report(node, "eval with argument of type " + node.arguments[0].type); | ||
} | ||
CallExpression: function (node) { | ||
if (node.callee.name === 'eval' && node.arguments[0].type !== 'Literal') { | ||
context.report(node, `eval with argument of type ${node.arguments[0].type}`); | ||
} | ||
} | ||
}; | ||
} | ||
}; |
@@ -1,19 +0,22 @@ | ||
module.exports = function (context) { | ||
// Detects instances of new Buffer(argument) | ||
// where argument is any non literal value. | ||
'use strict'; | ||
module.exports = { | ||
meta: { | ||
type: 'error', | ||
docs: { | ||
description: 'Detect instances of new Buffer(argument) where argument is any non-literal value.', | ||
category: 'Possible Security Vulnerability', | ||
recommended: true, | ||
url: 'https://github.com/nodesecurity/eslint-plugin-security/blob/main/README.md' | ||
} | ||
}, | ||
create: function (context) { | ||
return { | ||
"NewExpression": function (node) { | ||
if (node.callee.name === 'Buffer' && | ||
node.arguments[0] && | ||
node.arguments[0].type != 'Literal') { | ||
return context.report(node, "Found new Buffer"); | ||
NewExpression: function (node) { | ||
if (node.callee.name === 'Buffer' && node.arguments[0] && node.arguments[0].type !== 'Literal') { | ||
return context.report(node, 'Found new Buffer'); | ||
} | ||
} | ||
}; | ||
} | ||
} | ||
}; |
@@ -6,2 +6,4 @@ /** | ||
'use strict'; | ||
//------------------------------------------------------------------------------ | ||
@@ -11,31 +13,36 @@ // Rule Definition | ||
module.exports = { | ||
meta: { | ||
type: 'error', | ||
docs: { | ||
description: 'Detects Express "csrf" middleware setup before "method-override" middleware.', | ||
category: 'Possible Security Vulnerability', | ||
recommended: true, | ||
url: 'https://github.com/nodesecurity/eslint-plugin-security/blob/main/docs/bypass-connect-csrf-protection-by-abusing.md', | ||
}, | ||
}, | ||
create: function (context) { | ||
let csrf = false; | ||
module.exports = function(context) { | ||
"use strict"; | ||
var csrf = false; | ||
return { | ||
"CallExpression": function(node) { | ||
var token = context.getTokens(node)[0], | ||
nodeType = token.type, | ||
nodeValue = token.value; | ||
CallExpression: function (node) { | ||
const token = context.getTokens(node)[0]; | ||
const nodeValue = token.value; | ||
if (nodeValue === "express") { | ||
if (!node.callee || !node.callee.property) { | ||
return; | ||
} | ||
if (nodeValue === 'express') { | ||
if (!node.callee || !node.callee.property) { | ||
return; | ||
} | ||
if (node.callee.property.name === "methodOverride" && csrf) { | ||
context.report(node, "express.csrf() middleware found before express.methodOverride()"); | ||
} | ||
if (node.callee.property.name === "csrf") { | ||
// Keep track of found CSRF | ||
csrf = true; | ||
} | ||
} | ||
if (node.callee.property.name === 'methodOverride' && csrf) { | ||
context.report(node, 'express.csrf() middleware found before express.methodOverride()'); | ||
} | ||
if (node.callee.property.name === 'csrf') { | ||
// Keep track of found CSRF | ||
csrf = true; | ||
} | ||
} | ||
}, | ||
}; | ||
}, | ||
}; | ||
@@ -6,2 +6,4 @@ /** | ||
'use strict'; | ||
//------------------------------------------------------------------------------ | ||
@@ -11,41 +13,44 @@ // Rule Definition | ||
var names = []; | ||
var fsMetaData = require('./data/fsFunctionData.json'); | ||
var funcNames = Object.keys(fsMetaData); | ||
const fsMetaData = require('./data/fsFunctionData.json'); | ||
const funcNames = Object.keys(fsMetaData); | ||
module.exports = function(context) { | ||
"use strict"; | ||
module.exports = { | ||
meta: { | ||
type: 'error', | ||
docs: { | ||
description: 'Detects variable in filename argument of "fs" calls, which might allow an attacker to access anything on your system.', | ||
category: 'Possible Security Vulnerability', | ||
recommended: true, | ||
url: 'https://github.com/nodesecurity/eslint-plugin-security#detect-non-literal-fs-filename', | ||
}, | ||
}, | ||
create: function (context) { | ||
return { | ||
"MemberExpression": function (node) { | ||
var result = []; | ||
if (funcNames.indexOf(node.property.name) !== -1) { | ||
var meta = fsMetaData[node.property.name]; | ||
var args = node.parent.arguments; | ||
meta.forEach(function (i) { | ||
if (args && args.length > i) { | ||
if (args[i].type !== 'Literal') { | ||
result.push(i); | ||
} | ||
} | ||
}); | ||
MemberExpression: function (node) { | ||
const result = []; | ||
if (funcNames.indexOf(node.property.name) !== -1) { | ||
const meta = fsMetaData[node.property.name]; | ||
const args = node.parent.arguments; | ||
meta.forEach((i) => { | ||
if (args && args.length > i) { | ||
if (args[i].type !== 'Literal') { | ||
result.push(i); | ||
} | ||
} | ||
}); | ||
} | ||
if (result.length > 0) { | ||
var token = context.getTokens(node)[0]; | ||
return context.report(node, 'Found fs.' + node.property.name + ' with non literal argument at index ' + result.join(',')); | ||
} | ||
if (result.length > 0) { | ||
return context.report(node, `Found fs.${node.property.name} with non literal argument at index ${result.join(',')}`); | ||
} | ||
/* | ||
if (node.parent && node.parent.arguments && node.parent.arguments[index].value) { | ||
return context.report(node, 'found Buffer.' + node.property.name + ' with noAssert flag set true'); | ||
/* | ||
if (node.parent && node.parent.arguments && node.parent.arguments[index].value) { | ||
return context.report(node, 'found Buffer.' + node.property.name + ' with noAssert flag set true'); | ||
} | ||
*/ | ||
} | ||
} | ||
*/ | ||
}, | ||
}; | ||
}, | ||
}; |
@@ -6,2 +6,4 @@ /** | ||
'use strict'; | ||
//------------------------------------------------------------------------------ | ||
@@ -11,20 +13,24 @@ // Rule Definition | ||
module.exports = function(context) { | ||
"use strict"; | ||
return { | ||
"NewExpression": function(node) { | ||
if (node.callee.name === 'RegExp') { | ||
var args = node.arguments; | ||
if (args && args.length > 0 && args[0].type !== 'Literal') { | ||
var token = context.getTokens(node)[0]; | ||
return context.report(node, 'Found non-literal argument to RegExp Constructor'); | ||
} | ||
} | ||
} | ||
module.exports = { | ||
meta: { | ||
type: 'error', | ||
docs: { | ||
description: 'Detects "RegExp(variable)", which might allow an attacker to DOS your server with a long-running regular expression.', | ||
category: 'Possible Security Vulnerability', | ||
recommended: true, | ||
url: 'https://github.com/nodesecurity/eslint-plugin-security/blob/main/docs/regular-expression-dos-and-node.md', | ||
}, | ||
}, | ||
create: function (context) { | ||
return { | ||
NewExpression: function (node) { | ||
if (node.callee.name === 'RegExp') { | ||
const args = node.arguments; | ||
if (args && args.length > 0 && args[0].type !== 'Literal') { | ||
return context.report(node, 'Found non-literal argument to RegExp Constructor'); | ||
} | ||
} | ||
} | ||
}, | ||
}; | ||
}, | ||
}; |
/** | ||
* Tries to detect calls to require with non-literal argument | ||
* @author Adam Baldwin | ||
* @author Adam Baldwin | ||
*/ | ||
'use strict'; | ||
//------------------------------------------------------------------------------ | ||
@@ -10,21 +12,27 @@ // Rule Definition | ||
module.exports = function(context) { | ||
"use strict"; | ||
module.exports = { | ||
meta: { | ||
type: 'error', | ||
docs: { | ||
description: 'Detects "require(variable)", which might allow an attacker to load and run arbitrary code, or access arbitrary files on disk. ', | ||
category: 'Possible Security Vulnerability', | ||
recommended: true, | ||
url: 'https://github.com/nodesecurity/eslint-plugin-security#detect-non-literal-require', | ||
}, | ||
}, | ||
create: function (context) { | ||
return { | ||
"CallExpression": function (node) { | ||
if (node.callee.name === 'require') { | ||
var args = node.arguments; | ||
if (args && args.length > 0 && args[0].type !== 'Literal') { | ||
var token = context.getTokens(node)[0]; | ||
return context.report(node, 'Found non-literal argument in require'); | ||
} | ||
} | ||
CallExpression: function (node) { | ||
if (node.callee.name === 'require') { | ||
const args = node.arguments; | ||
if ( | ||
(args && args.length > 0 && args[0].type === 'TemplateLiteral' && args[0].expressions.length > 0) || | ||
(args[0].type !== 'TemplateLiteral' && args[0].type !== 'Literal') | ||
) { | ||
return context.report(node, 'Found non-literal argument in require'); | ||
} | ||
} | ||
}, | ||
}; | ||
}, | ||
}; | ||
@@ -6,2 +6,4 @@ /** | ||
'use strict'; | ||
//------------------------------------------------------------------------------ | ||
@@ -11,14 +13,28 @@ // Rule Definition | ||
var Sinks = []; | ||
function getSerialize (fn, decycle) { | ||
var seen = [], keys = []; | ||
decycle = decycle || function(key, value) { | ||
return '[Circular ' + getPath(value, seen, keys) + ']' | ||
}; | ||
return function(key, value) { | ||
var ret = value; | ||
const getPath = (value, seen, keys) => { | ||
let index = seen.indexOf(value); | ||
const path = [keys[index]]; | ||
for (index--; index >= 0; index--) { | ||
if (seen[index][path[0]] === value) { | ||
value = seen[index]; | ||
path.unshift(keys[index]); | ||
} | ||
} | ||
return `~${path.join('.')}`; | ||
}; | ||
const getSerialize = (fn, decycle) => { | ||
const seen = []; | ||
const keys = []; | ||
decycle = | ||
decycle || | ||
function (key, value) { | ||
return `[Circular ${getPath(value, seen, keys)}]`; | ||
}; | ||
return function (key, value) { | ||
let ret = value; | ||
if (typeof value === 'object' && value) { | ||
if (seen.indexOf(value) !== -1) | ||
if (seen.indexOf(value) !== -1) { | ||
ret = decycle(key, value); | ||
else { | ||
} else { | ||
seen.push(value); | ||
@@ -28,55 +44,41 @@ keys.push(key); | ||
} | ||
if (fn) ret = fn(key, ret); | ||
if (fn) { | ||
ret = fn(key, ret); | ||
} | ||
return ret; | ||
} | ||
} | ||
}; | ||
}; | ||
function getPath (value, seen, keys) { | ||
var index = seen.indexOf(value); | ||
var path = [ keys[index] ]; | ||
for (index--; index >= 0; index--) { | ||
if (seen[index][ path[0] ] === value) { | ||
value = seen[index]; | ||
path.unshift(keys[index]); | ||
} | ||
} | ||
return '~' + path.join('.'); | ||
} | ||
function stringify(obj, fn, spaces, decycle) { | ||
const stringify = (obj, fn, spaces, decycle) => { | ||
return JSON.stringify(obj, getSerialize(fn, decycle), spaces); | ||
} | ||
}; | ||
stringify.getSerialize = getSerialize;module.exports = function(context) { | ||
"use strict"; | ||
var isChanged = false; | ||
return { | ||
"MemberExpression": function(node) { | ||
if (node.computed === true) { | ||
var token = context.getTokens(node)[0]; | ||
if (node.property.type === 'Identifier') { | ||
if (node.parent.type === 'VariableDeclarator') { | ||
context.report(node, 'Variable Assigned to Object Injection Sink'); | ||
} else if (node.parent.type === 'CallExpression') { | ||
// console.log(node.parent) | ||
context.report(node, 'Function Call Object Injection Sink'); | ||
} else { | ||
context.report(node, 'Generic Object Injection Sink'); | ||
} | ||
} | ||
} | ||
stringify.getSerialize = getSerialize; | ||
module.exports = { | ||
meta: { | ||
type: 'error', | ||
docs: { | ||
description: 'Detects "variable[key]" as a left- or right-hand assignment operand.', | ||
category: 'Possible Security Vulnerability', | ||
recommended: true, | ||
url: 'https://github.com/nodesecurity/eslint-plugin-security/blob/main/docs/the-dangers-of-square-bracket-notation.md', | ||
}, | ||
}, | ||
create: function (context) { | ||
return { | ||
MemberExpression: function (node) { | ||
if (node.computed === true) { | ||
if (node.property.type === 'Identifier') { | ||
if (node.parent.type === 'VariableDeclarator') { | ||
context.report(node, 'Variable Assigned to Object Injection Sink'); | ||
} else if (node.parent.type === 'CallExpression') { | ||
context.report(node, 'Function Call Object Injection Sink'); | ||
} else { | ||
context.report(node, 'Generic Object Injection Sink'); | ||
} | ||
}; | ||
} | ||
} | ||
} | ||
}, | ||
}; | ||
}, | ||
}; |
@@ -6,2 +6,4 @@ /** | ||
'use strict'; | ||
//------------------------------------------------------------------------------ | ||
@@ -11,52 +13,48 @@ // Rule Definition | ||
var keywords = '((' + [ | ||
'password', | ||
'secret', | ||
'api', | ||
'apiKey', | ||
'token', | ||
'auth', | ||
'pass', | ||
'hash' | ||
].join(')|(') + '))'; | ||
const keywords = `((${['password', 'secret', 'api', 'apiKey', 'token', 'auth', 'pass', 'hash'].join(')|(')}))`; | ||
var re = new RegExp('^' + keywords + '$', 'im'); | ||
const re = new RegExp(`^${keywords}$`, 'im'); | ||
function containsKeyword (node) { | ||
if (node.type === 'Identifier') { | ||
if (re.test(node.name)) | ||
return true; | ||
} | ||
return | ||
} | ||
const containsKeyword = (node) => { | ||
if (node.type === 'Identifier') { | ||
if (re.test(node.name)) { | ||
return true; | ||
} | ||
} | ||
return; | ||
}; | ||
module.exports = function(context) { | ||
"use strict"; | ||
module.exports = { | ||
meta: { | ||
type: 'error', | ||
docs: { | ||
description: 'Detects insecure comparisons (`==`, `!=`, `!==` and `===`), which check input sequentially.', | ||
category: 'Possible Security Vulnerability', | ||
recommended: true, | ||
url: 'https://github.com/nodesecurity/eslint-plugin-security#detect-possible-timing-attacks' | ||
} | ||
}, | ||
create: function (context) { | ||
return { | ||
"IfStatement": function(node) { | ||
if (node.test && node.test.type === 'BinaryExpression') { | ||
if (node.test.operator === '==' || node.test.operator === '===' || node.test.operator === '!=' || node.test.operator === '!==') { | ||
IfStatement: function (node) { | ||
if (node.test && node.test.type === 'BinaryExpression') { | ||
if (node.test.operator === '==' || node.test.operator === '===' || node.test.operator === '!=' || node.test.operator === '!==') { | ||
if (node.test.left) { | ||
const left = containsKeyword(node.test.left); | ||
if (left) { | ||
return context.report(node, `Potential timing attack, left side: ${left}`); | ||
} | ||
} | ||
var token = context.getTokens(node)[0]; | ||
if (node.test.left) { | ||
var left = containsKeyword(node.test.left); | ||
if (left) { | ||
return context.report(node, "Potential timing attack, left side: " + left); | ||
} | ||
} | ||
if (node.test.right) { | ||
var right = containsKeyword(node.test.right); | ||
if (right) { | ||
return context.report(node, "Potential timing attack, right side: " + right); | ||
} | ||
} | ||
} | ||
if (node.test.right) { | ||
const right = containsKeyword(node.test.right); | ||
if (right) { | ||
return context.report(node, `Potential timing attack, right side: ${right}`); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
} | ||
}; |
@@ -6,2 +6,4 @@ /** | ||
'use strict'; | ||
//------------------------------------------------------------------------------ | ||
@@ -11,16 +13,21 @@ // Rule Definition | ||
module.exports = function(context) { | ||
"use strict"; | ||
module.exports = { | ||
meta: { | ||
type: 'error', | ||
docs: { | ||
description: 'Detects if "pseudoRandomBytes()" is in use, which might not give you the randomness you need and expect.', | ||
category: 'Possible Security Vulnerability', | ||
recommended: true, | ||
url: 'https://github.com/nodesecurity/eslint-plugin-security#detect-pseudorandombytes', | ||
}, | ||
}, | ||
create: function (context) { | ||
return { | ||
"MemberExpression": function (node) { | ||
if (node.property.name === 'pseudoRandomBytes') { | ||
var token = context.getTokens(node)[0]; | ||
return context.report(node, 'Found crypto.pseudoRandomBytes which does not produce cryptographically strong numbers'); | ||
} | ||
MemberExpression: function (node) { | ||
if (node.property.name === 'pseudoRandomBytes') { | ||
return context.report(node, 'Found crypto.pseudoRandomBytes which does not produce cryptographically strong numbers'); | ||
} | ||
}, | ||
}; | ||
}, | ||
}; |
@@ -1,2 +0,1 @@ | ||
var safe = require('safe-regex'); | ||
/** | ||
@@ -7,2 +6,10 @@ * Check if the regex is evil or not using the safe-regex module | ||
'use strict'; | ||
//----------------------------------------------------------------------------- | ||
// Requirements | ||
//----------------------------------------------------------------------------- | ||
const safe = require('safe-regex'); | ||
//------------------------------------------------------------------------------ | ||
@@ -12,28 +19,34 @@ // Rule Definition | ||
module.exports = function(context) { | ||
"use strict"; | ||
module.exports = { | ||
meta: { | ||
type: 'error', | ||
docs: { | ||
description: 'Locates potentially unsafe regular expressions, which may take a very long time to run, blocking the event loop.', | ||
category: 'Possible Security Vulnerability', | ||
recommended: true, | ||
url: 'https://github.com/nodesecurity/eslint-plugin-security/blob/main/docs/regular-expression-dos-and-node.md' | ||
} | ||
}, | ||
create: function (context) { | ||
return { | ||
"Literal": function(node) { | ||
var token = context.getTokens(node)[0], | ||
nodeType = token.type, | ||
nodeValue = token.value; | ||
Literal: function (node) { | ||
const token = context.getTokens(node)[0]; | ||
const nodeType = token.type; | ||
const nodeValue = token.value; | ||
if (nodeType === "RegularExpression") { | ||
if (!safe(nodeValue)) { | ||
context.report(node, "Unsafe Regular Expression"); | ||
} | ||
} | ||
}, | ||
"NewExpression": function(node) { | ||
if (node.callee.name == "RegExp" && node.arguments && node.arguments.length > 0 && node.arguments[0].type == "Literal") { | ||
if (!safe(node.arguments[0].value)) { | ||
context.report(node, "Unsafe Regular Expression (new RegExp)"); | ||
} | ||
} | ||
if (nodeType === 'RegularExpression') { | ||
if (!safe(nodeValue)) { | ||
context.report(node, 'Unsafe Regular Expression'); | ||
} | ||
} | ||
}, | ||
NewExpression: function (node) { | ||
if (node.callee.name === 'RegExp' && node.arguments && node.arguments.length > 0 && node.arguments[0].type === 'Literal') { | ||
if (!safe(node.arguments[0].value)) { | ||
context.report(node, 'Unsafe Regular Expression (new RegExp)'); | ||
} | ||
} | ||
} | ||
}; | ||
} | ||
}; | ||
@@ -7,25 +7,25 @@ 'use strict'; | ||
const ruleName = 'detect-buffer-noassert'; | ||
const Rule = require(`../rules/${ruleName}`); | ||
const rule = require(`../rules/${ruleName}`); | ||
const invalid = 'a.readUInt8(0, true);'; | ||
const allMethodNames = [...rule.meta.__methodsToCheck.read, ...rule.meta.__methodsToCheck.write]; | ||
tester.run(ruleName, Rule, { | ||
valid: [{ code: 'a.readUInt8(0);' }], | ||
tester.run(ruleName, rule, { | ||
valid: [...allMethodNames.map((methodName) => `a.${methodName}(0)`), ...allMethodNames.map((methodName) => `a.${methodName}(0, false)`)], | ||
invalid: [ | ||
{ | ||
code: invalid, | ||
errors: [{ message: 'Found Buffer.readUInt8 with noAssert flag set true' }] | ||
} | ||
] | ||
}); | ||
...rule.meta.__methodsToCheck.read.map((methodName) => ({ | ||
code: `a.${methodName}(0, true)`, | ||
errors: [{ message: `Found Buffer.${methodName} with noAssert flag set true` }], | ||
})), | ||
tester.run(`${ruleName} (false)`, Rule, { | ||
valid: [{ code: 'a.readUInt8(0, false);' }], | ||
invalid: [ | ||
...rule.meta.__methodsToCheck.write.map((methodName) => ({ | ||
code: `a.${methodName}(0, 0, true)`, | ||
errors: [{ message: `Found Buffer.${methodName} with noAssert flag set true` }], | ||
})), | ||
// hard-coded test to ensure #63 is fixed | ||
{ | ||
code: invalid, | ||
errors: [{ message: 'Found Buffer.readUInt8 with noAssert flag set true' }] | ||
} | ||
] | ||
code: 'a.readDoubleLE(0, true);', | ||
errors: [{ message: 'Found Buffer.readDoubleLE with noAssert flag set true' }], | ||
}, | ||
], | ||
}); |
@@ -7,30 +7,20 @@ 'use strict'; | ||
const ruleName = 'detect-child-process'; | ||
const Rule = require(`../rules/${ruleName}`); | ||
const rule = require(`../rules/${ruleName}`); | ||
const valid = 'child_process.exec(\'ls\')'; | ||
const invalidRequire = 'require(\'child_process\')'; | ||
const invalidExec = 'var child = require(\'child_process\'); child.exec(com)'; | ||
tester.run(`${ruleName} (require("child_process"))`, Rule, { | ||
valid: [{ code: valid }], | ||
tester.run(ruleName, rule, { | ||
valid: ["child_process.exec('ls')"], | ||
invalid: [ | ||
{ | ||
code: invalidRequire, | ||
errors: [{ message: 'Found require("child_process")' }] | ||
} | ||
] | ||
}); | ||
tester.run(`${ruleName} (child_process.exec() wih non literal 1st arg.)`, Rule, { | ||
valid: [{ code: valid }], | ||
invalid: [ | ||
code: "require('child_process')", | ||
errors: [{ message: 'Found require("child_process")' }], | ||
}, | ||
{ | ||
code: invalidExec, | ||
errors: [ | ||
{ message: 'Found require("child_process")' }, | ||
{ message: 'Found child_process.exec() with non Literal first argument' }] | ||
} | ||
] | ||
code: "var child = require('child_process'); child.exec(com)", | ||
errors: [{ message: 'Found require("child_process")' }, { message: 'Found child_process.exec() with non Literal first argument' }], | ||
}, | ||
{ | ||
code: "var child = require('child_process'); child.exec()", | ||
errors: [{ message: 'Found require("child_process")' }], | ||
}, | ||
], | ||
}); |
@@ -8,3 +8,2 @@ 'use strict'; | ||
tester.run(ruleName, require(`../rules/${ruleName}`), { | ||
@@ -11,0 +10,0 @@ valid: [{ code: 'escapeMarkup = false' }], |
@@ -8,3 +8,2 @@ 'use strict'; | ||
tester.run(ruleName, require(`../rules/${ruleName}`), { | ||
@@ -11,0 +10,0 @@ valid: [{ code: 'eval(\'alert()\')' }], |
@@ -9,3 +9,2 @@ 'use strict'; | ||
tester.run(ruleName, require(`../rules/${ruleName}`), { | ||
@@ -12,0 +11,0 @@ valid: [{ code: 'var a = new Buffer(\'test\')' }], |
@@ -8,3 +8,2 @@ 'use strict'; | ||
tester.run(ruleName, require(`../rules/${ruleName}`), { | ||
@@ -11,0 +10,0 @@ valid: [{ code: 'express.methodOverride();express.csrf()' }], |
@@ -10,3 +10,2 @@ 'use strict'; | ||
tester.run(ruleName, require(`../rules/${ruleName}`), { | ||
@@ -13,0 +12,0 @@ valid: [{ code: 'var a = fs.open(\'test\')' }], |
@@ -9,3 +9,2 @@ 'use strict'; | ||
tester.run(ruleName, require(`../rules/${ruleName}`), { | ||
@@ -12,0 +11,0 @@ valid: [{ code: 'var a = new RegExp(\'ab+c\', \'i\')' }], |
'use strict'; | ||
const RuleTester = require('eslint').RuleTester; | ||
const tester = new RuleTester(); | ||
const tester = new RuleTester({ parserOptions: { ecmaVersion: 6 } }); | ||
const ruleName = 'detect-non-literal-require'; | ||
const invalid = 'var a = require(c)'; | ||
tester.run(ruleName, require(`../rules/${ruleName}`), { | ||
valid: [{ code: 'var a = require(\'b\')' }], | ||
valid: [{ code: 'var a = require(\'b\')' }, { code: 'var a = require(`b`)' }], | ||
invalid: [ | ||
{ | ||
code: invalid, | ||
code: 'var a = require(c)', | ||
errors: [{ message: 'Found non-literal argument in require' }] | ||
}, | ||
{ | ||
code: 'var a = require(`${c}`)', | ||
errors: [{ message: 'Found non-literal argument in require' }] | ||
} | ||
] | ||
}); |
@@ -15,3 +15,2 @@ 'use strict'; | ||
// TODO | ||
@@ -39,3 +38,2 @@ // tester.run(`${ruleName} (Variable Assigned to)`, Rule, { | ||
tester.run(`${ruleName} (Generic)`, Rule, { | ||
@@ -42,0 +40,0 @@ valid: [{ code: valid }], |
@@ -13,3 +13,2 @@ 'use strict'; | ||
// We only check with one string "password" and operator "===" | ||
@@ -28,3 +27,2 @@ // to KISS. | ||
tester.run(`${ruleName} (right side)`, Rule, { | ||
@@ -31,0 +29,0 @@ valid: [{ code: valid }], |
@@ -9,3 +9,2 @@ 'use strict'; | ||
tester.run(ruleName, require(`../rules/${ruleName}`), { | ||
@@ -12,0 +11,0 @@ valid: [{ code: 'crypto.randomBytes' }], |
@@ -9,5 +9,4 @@ 'use strict'; | ||
tester.run(ruleName, Rule, { | ||
valid: [{ code: '/^\d+1337\d+$/' }], | ||
valid: [{ code: '/^d+1337d+$/' }], | ||
invalid: [ | ||
@@ -21,5 +20,4 @@ { | ||
tester.run(`${ruleName} (new RegExp)`, Rule, { | ||
valid: [{ code: 'new RegExp(\'^\d+1337\d+$\')' }], | ||
valid: [{ code: 'new RegExp(\'^d+1337d+$\')' }], | ||
invalid: [ | ||
@@ -26,0 +24,0 @@ { |
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
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
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
67789
40
908
115
9
1
+ Addedregexp-tree@0.1.27(transitive)
+ Addedsafe-regex@2.1.1(transitive)
- Removedret@0.1.15(transitive)
- Removedsafe-regex@1.1.0(transitive)
Updatedsafe-regex@^2.1.1