eslint-plugin-security 1.5.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslint-doc-generatorrc.js +9 -0
- package/.eslintrc +23 -5
- package/.github/ISSUE_TEMPLATE/bug-report.yml +85 -0
- package/.github/ISSUE_TEMPLATE/new-rule.yml +39 -0
- package/.github/ISSUE_TEMPLATE/rule-change.yml +61 -0
- package/.github/workflows/ci.yml +13 -5
- package/.github/workflows/pr.yml +6 -2
- package/.github/workflows/release-please.yml +39 -0
- package/.markdownlint.json +4 -0
- package/.markdownlintignore +3 -0
- package/.prettierignore +1 -0
- package/CHANGELOG.md +70 -15
- package/README.md +39 -81
- package/docs/bypass-connect-csrf-protection-by-abusing.md +3 -3
- package/docs/rules/detect-bidi-characters.md +50 -0
- package/docs/rules/detect-buffer-noassert.md +9 -0
- package/docs/rules/detect-child-process.md +9 -0
- package/docs/rules/detect-disable-mustache-escape.md +9 -0
- package/docs/rules/detect-eval-with-expression.md +7 -0
- package/docs/rules/detect-new-buffer.md +5 -0
- package/docs/rules/detect-no-csrf-before-method-override.md +9 -0
- package/docs/rules/detect-non-literal-fs-filename.md +7 -0
- package/docs/rules/detect-non-literal-regexp.md +7 -0
- package/docs/rules/detect-non-literal-require.md +7 -0
- package/docs/rules/detect-object-injection.md +7 -0
- package/docs/rules/detect-possible-timing-attacks.md +5 -0
- package/docs/rules/detect-pseudoRandomBytes.md +5 -0
- package/docs/rules/detect-unsafe-regex.md +7 -0
- package/docs/the-dangers-of-square-bracket-notation.md +11 -11
- package/index.js +9 -6
- package/package.json +17 -9
- package/rules/detect-bidi-characters.js +101 -0
- package/rules/detect-buffer-noassert.js +3 -3
- package/rules/detect-child-process.js +29 -20
- package/rules/detect-disable-mustache-escape.js +5 -5
- package/rules/detect-eval-with-expression.js +5 -5
- package/rules/detect-new-buffer.js +6 -6
- package/rules/detect-no-csrf-before-method-override.js +3 -3
- package/rules/detect-non-literal-fs-filename.js +71 -23
- package/rules/detect-non-literal-regexp.js +2 -2
- package/rules/detect-non-literal-require.js +3 -3
- package/rules/detect-object-injection.js +4 -4
- package/rules/detect-possible-timing-attacks.js +6 -6
- package/rules/detect-pseudoRandomBytes.js +2 -2
- package/rules/detect-unsafe-regex.js +8 -8
- package/test/detect-bidi-characters.js +74 -0
- package/test/detect-child-process.js +115 -4
- package/test/detect-disable-mustache-escape.js +3 -3
- package/test/detect-eval-with-expression.js +4 -4
- package/test/detect-new-buffer.js +4 -4
- package/test/detect-no-csrf-before-method-override.js +3 -3
- package/test/detect-non-literal-fs-filename.js +135 -8
- package/test/detect-non-literal-regexp.js +5 -5
- package/test/detect-non-literal-require.js +5 -5
- package/test/detect-object-injection.js +3 -3
- package/test/detect-possible-timing-attacks.js +8 -8
- package/test/detect-pseudoRandomBytes.js +3 -3
- package/test/detect-unsafe-regexp.js +8 -8
- package/test/utils/import-utils.js +172 -0
- package/{rules → utils}/data/fsFunctionData.json +0 -0
- package/utils/import-utils.js +196 -0
|
@@ -5,12 +5,30 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
|
+
const fsMetaData = require('../utils/data/fsFunctionData.json');
|
|
9
|
+
const funcNames = Object.keys(fsMetaData);
|
|
10
|
+
const fsPackageNames = ['fs', 'node:fs', 'fs/promises', 'node:fs/promises', 'fs-extra'];
|
|
11
|
+
|
|
12
|
+
const { getImportAccessPath } = require('../utils/import-utils');
|
|
13
|
+
|
|
8
14
|
//------------------------------------------------------------------------------
|
|
9
|
-
//
|
|
15
|
+
// Utils
|
|
10
16
|
//------------------------------------------------------------------------------
|
|
11
17
|
|
|
12
|
-
|
|
13
|
-
|
|
18
|
+
function getIndices(node, argMeta) {
|
|
19
|
+
return (argMeta || []).filter((argIndex) => node.arguments[argIndex].type !== 'Literal');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function generateReport({ context, node, packageName, methodName, indices }) {
|
|
23
|
+
if (!indices || indices.length === 0) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
context.report({ node, message: `Found ${methodName} from package "${packageName}" with non literal argument at index ${indices.join(',')}` });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
//------------------------------------------------------------------------------
|
|
30
|
+
// Rule Definition
|
|
31
|
+
//------------------------------------------------------------------------------
|
|
14
32
|
|
|
15
33
|
module.exports = {
|
|
16
34
|
meta: {
|
|
@@ -19,35 +37,65 @@ module.exports = {
|
|
|
19
37
|
description: 'Detects variable in filename argument of "fs" calls, which might allow an attacker to access anything on your system.',
|
|
20
38
|
category: 'Possible Security Vulnerability',
|
|
21
39
|
recommended: true,
|
|
22
|
-
url: 'https://github.com/
|
|
40
|
+
url: 'https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-non-literal-fs-filename.md',
|
|
23
41
|
},
|
|
24
42
|
},
|
|
25
43
|
create: function (context) {
|
|
26
44
|
return {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (
|
|
30
|
-
|
|
31
|
-
const args = node.parent.arguments;
|
|
32
|
-
meta.forEach((i) => {
|
|
33
|
-
if (args && args.length > i) {
|
|
34
|
-
if (args[i].type !== 'Literal') {
|
|
35
|
-
result.push(i);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
});
|
|
45
|
+
CallExpression: function (node) {
|
|
46
|
+
// don't check require. If all arguments are Literals, it's surely safe!
|
|
47
|
+
if ((node.callee.type === 'Identifier' && node.callee.name === 'require') || node.arguments.every((argument) => argument.type === 'Literal')) {
|
|
48
|
+
return;
|
|
39
49
|
}
|
|
40
50
|
|
|
41
|
-
|
|
42
|
-
|
|
51
|
+
const pathInfo = getImportAccessPath({
|
|
52
|
+
node: node.callee,
|
|
53
|
+
scope: context.getScope(),
|
|
54
|
+
packageNames: fsPackageNames,
|
|
55
|
+
});
|
|
56
|
+
if (!pathInfo) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
let fnName;
|
|
60
|
+
if (pathInfo.path.length === 1) {
|
|
61
|
+
// Check for:
|
|
62
|
+
// | var something = require('fs').readFile;
|
|
63
|
+
// | something(a);
|
|
64
|
+
// ,
|
|
65
|
+
// | var something = require('fs');
|
|
66
|
+
// | something.readFile(c);
|
|
67
|
+
// ,
|
|
68
|
+
// | var { readFile: something } = require('fs')
|
|
69
|
+
// | readFile(filename);
|
|
70
|
+
// ,
|
|
71
|
+
// | import { readFile as something } from 'fs';
|
|
72
|
+
// | something(filename);
|
|
73
|
+
// , or
|
|
74
|
+
// | import * as something from 'fs';
|
|
75
|
+
// | something.readFile(c);
|
|
76
|
+
fnName = pathInfo.path[0];
|
|
77
|
+
} else if (pathInfo.path.length === 2) {
|
|
78
|
+
// Check for:
|
|
79
|
+
// | var something = require('fs').promises;
|
|
80
|
+
// | something.readFile(filename)
|
|
81
|
+
fnName = pathInfo.path[1];
|
|
82
|
+
} else {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (!funcNames.includes(fnName)) {
|
|
86
|
+
return false;
|
|
43
87
|
}
|
|
88
|
+
const packageName = pathInfo.packageName;
|
|
44
89
|
|
|
45
|
-
|
|
46
|
-
if (node.parent && node.parent.arguments && node.parent.arguments[index].value) {
|
|
47
|
-
return context.report(node, 'found Buffer.' + node.property.name + ' with noAssert flag set true');
|
|
90
|
+
const indices = getIndices(node, fsMetaData[fnName]);
|
|
48
91
|
|
|
49
|
-
|
|
50
|
-
|
|
92
|
+
generateReport({
|
|
93
|
+
context,
|
|
94
|
+
node,
|
|
95
|
+
packageName,
|
|
96
|
+
methodName: fnName,
|
|
97
|
+
indices,
|
|
98
|
+
});
|
|
51
99
|
},
|
|
52
100
|
};
|
|
53
101
|
},
|
|
@@ -16,7 +16,7 @@ module.exports = {
|
|
|
16
16
|
description: 'Detects "RegExp(variable)", which might allow an attacker to DOS your server with a long-running regular expression.',
|
|
17
17
|
category: 'Possible Security Vulnerability',
|
|
18
18
|
recommended: true,
|
|
19
|
-
url: 'https://github.com/
|
|
19
|
+
url: 'https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-non-literal-regexp.md',
|
|
20
20
|
},
|
|
21
21
|
},
|
|
22
22
|
create: function (context) {
|
|
@@ -25,7 +25,7 @@ module.exports = {
|
|
|
25
25
|
if (node.callee.name === 'RegExp') {
|
|
26
26
|
const args = node.arguments;
|
|
27
27
|
if (args && args.length > 0 && args[0].type !== 'Literal') {
|
|
28
|
-
return context.report(node, 'Found non-literal argument to RegExp Constructor');
|
|
28
|
+
return context.report({ node: node, message: 'Found non-literal argument to RegExp Constructor' });
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
},
|
|
@@ -13,10 +13,10 @@ module.exports = {
|
|
|
13
13
|
meta: {
|
|
14
14
|
type: 'error',
|
|
15
15
|
docs: {
|
|
16
|
-
description: 'Detects "require(variable)", which might allow an attacker to load and run arbitrary code, or access arbitrary files on disk.
|
|
16
|
+
description: 'Detects "require(variable)", which might allow an attacker to load and run arbitrary code, or access arbitrary files on disk.',
|
|
17
17
|
category: 'Possible Security Vulnerability',
|
|
18
18
|
recommended: true,
|
|
19
|
-
url: 'https://github.com/
|
|
19
|
+
url: 'https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-non-literal-require.md',
|
|
20
20
|
},
|
|
21
21
|
},
|
|
22
22
|
create: function (context) {
|
|
@@ -28,7 +28,7 @@ module.exports = {
|
|
|
28
28
|
(args && args.length > 0 && args[0].type === 'TemplateLiteral' && args[0].expressions.length > 0) ||
|
|
29
29
|
(args[0].type !== 'TemplateLiteral' && args[0].type !== 'Literal')
|
|
30
30
|
) {
|
|
31
|
-
return context.report(node, 'Found non-literal argument in require');
|
|
31
|
+
return context.report({ node: node, message: 'Found non-literal argument in require' });
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
},
|
|
@@ -58,7 +58,7 @@ module.exports = {
|
|
|
58
58
|
description: 'Detects "variable[key]" as a left- or right-hand assignment operand.',
|
|
59
59
|
category: 'Possible Security Vulnerability',
|
|
60
60
|
recommended: true,
|
|
61
|
-
url: 'https://github.com/
|
|
61
|
+
url: 'https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-object-injection.md',
|
|
62
62
|
},
|
|
63
63
|
},
|
|
64
64
|
create: function (context) {
|
|
@@ -67,11 +67,11 @@ module.exports = {
|
|
|
67
67
|
if (node.computed === true) {
|
|
68
68
|
if (node.property.type === 'Identifier') {
|
|
69
69
|
if (node.parent.type === 'VariableDeclarator') {
|
|
70
|
-
context.report(node, 'Variable Assigned to Object Injection Sink');
|
|
70
|
+
context.report({ node: node, message: 'Variable Assigned to Object Injection Sink' });
|
|
71
71
|
} else if (node.parent.type === 'CallExpression') {
|
|
72
|
-
context.report(node, 'Function Call Object Injection Sink');
|
|
72
|
+
context.report({ node: node, message: 'Function Call Object Injection Sink' });
|
|
73
73
|
} else {
|
|
74
|
-
context.report(node, 'Generic Object Injection Sink');
|
|
74
|
+
context.report({ node: node, message: 'Generic Object Injection Sink' });
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
}
|
|
@@ -29,8 +29,8 @@ module.exports = {
|
|
|
29
29
|
description: 'Detects insecure comparisons (`==`, `!=`, `!==` and `===`), which check input sequentially.',
|
|
30
30
|
category: 'Possible Security Vulnerability',
|
|
31
31
|
recommended: true,
|
|
32
|
-
url: 'https://github.com/
|
|
33
|
-
}
|
|
32
|
+
url: 'https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-possible-timing-attacks.md',
|
|
33
|
+
},
|
|
34
34
|
},
|
|
35
35
|
create: function (context) {
|
|
36
36
|
return {
|
|
@@ -40,19 +40,19 @@ module.exports = {
|
|
|
40
40
|
if (node.test.left) {
|
|
41
41
|
const left = containsKeyword(node.test.left);
|
|
42
42
|
if (left) {
|
|
43
|
-
return context.report(node, `Potential timing attack, left side: ${left}`);
|
|
43
|
+
return context.report({ node: node, message: `Potential timing attack, left side: ${left}` });
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
if (node.test.right) {
|
|
48
48
|
const right = containsKeyword(node.test.right);
|
|
49
49
|
if (right) {
|
|
50
|
-
return context.report(node, `Potential timing attack, right side: ${right}`);
|
|
50
|
+
return context.report({ node: node, message: `Potential timing attack, right side: ${right}` });
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
-
}
|
|
55
|
+
},
|
|
56
56
|
};
|
|
57
|
-
}
|
|
57
|
+
},
|
|
58
58
|
};
|
|
@@ -16,14 +16,14 @@ module.exports = {
|
|
|
16
16
|
description: 'Detects if "pseudoRandomBytes()" is in use, which might not give you the randomness you need and expect.',
|
|
17
17
|
category: 'Possible Security Vulnerability',
|
|
18
18
|
recommended: true,
|
|
19
|
-
url: 'https://github.com/
|
|
19
|
+
url: 'https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-pseudoRandomBytes.md',
|
|
20
20
|
},
|
|
21
21
|
},
|
|
22
22
|
create: function (context) {
|
|
23
23
|
return {
|
|
24
24
|
MemberExpression: function (node) {
|
|
25
25
|
if (node.property.name === 'pseudoRandomBytes') {
|
|
26
|
-
return context.report(node, 'Found crypto.pseudoRandomBytes which does not produce cryptographically strong numbers');
|
|
26
|
+
return context.report({ node: node, message: 'Found crypto.pseudoRandomBytes which does not produce cryptographically strong numbers' });
|
|
27
27
|
}
|
|
28
28
|
},
|
|
29
29
|
};
|
|
@@ -19,32 +19,32 @@ module.exports = {
|
|
|
19
19
|
meta: {
|
|
20
20
|
type: 'error',
|
|
21
21
|
docs: {
|
|
22
|
-
description: '
|
|
22
|
+
description: 'Detects potentially unsafe regular expressions, which may take a very long time to run, blocking the event loop.',
|
|
23
23
|
category: 'Possible Security Vulnerability',
|
|
24
24
|
recommended: true,
|
|
25
|
-
url: 'https://github.com/
|
|
26
|
-
}
|
|
25
|
+
url: 'https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-unsafe-regex.md',
|
|
26
|
+
},
|
|
27
27
|
},
|
|
28
28
|
create: function (context) {
|
|
29
29
|
return {
|
|
30
30
|
Literal: function (node) {
|
|
31
|
-
const token = context.getTokens(node)[0];
|
|
31
|
+
const token = context.getSourceCode().getTokens(node)[0];
|
|
32
32
|
const nodeType = token.type;
|
|
33
33
|
const nodeValue = token.value;
|
|
34
34
|
|
|
35
35
|
if (nodeType === 'RegularExpression') {
|
|
36
36
|
if (!safe(nodeValue)) {
|
|
37
|
-
context.report(node, 'Unsafe Regular Expression');
|
|
37
|
+
context.report({ node: node, message: 'Unsafe Regular Expression' });
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
},
|
|
41
41
|
NewExpression: function (node) {
|
|
42
42
|
if (node.callee.name === 'RegExp' && node.arguments && node.arguments.length > 0 && node.arguments[0].type === 'Literal') {
|
|
43
43
|
if (!safe(node.arguments[0].value)) {
|
|
44
|
-
context.report(node, 'Unsafe Regular Expression (new RegExp)');
|
|
44
|
+
context.report({ node: node, message: 'Unsafe Regular Expression (new RegExp)' });
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
-
}
|
|
47
|
+
},
|
|
48
48
|
};
|
|
49
|
-
}
|
|
49
|
+
},
|
|
50
50
|
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const RuleTester = require('eslint').RuleTester;
|
|
4
|
+
const tester = new RuleTester();
|
|
5
|
+
|
|
6
|
+
const ruleName = 'detect-bidi-characters';
|
|
7
|
+
const Rule = require(`../rules/${ruleName}`);
|
|
8
|
+
|
|
9
|
+
tester.run(ruleName, Rule, {
|
|
10
|
+
valid: [
|
|
11
|
+
{
|
|
12
|
+
code: `
|
|
13
|
+
var accessLevel = "user";
|
|
14
|
+
if (accessLevel != "user") { // Check if admin
|
|
15
|
+
console.log("You are an admin.");
|
|
16
|
+
}
|
|
17
|
+
`,
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
invalid: [
|
|
21
|
+
{
|
|
22
|
+
code: `
|
|
23
|
+
var accessLevel = "user";
|
|
24
|
+
if (accessLevel != "user // Check if admin ") {
|
|
25
|
+
console.log("You are an admin.");
|
|
26
|
+
}
|
|
27
|
+
`,
|
|
28
|
+
errors: [
|
|
29
|
+
{ message: /Detected potential trojan source attack with unicode bidi introduced in this code/i, line: 3, endLine: 3, column: 31, endColumn: 32 },
|
|
30
|
+
{ message: /Detected potential trojan source attack with unicode bidi introduced in this code/i, line: 3, endLine: 3, column: 33, endColumn: 34 },
|
|
31
|
+
{ message: /Detected potential trojan source attack with unicode bidi introduced in this code/i, line: 3, endLine: 3, column: 51, endColumn: 52 },
|
|
32
|
+
{ message: /Detected potential trojan source attack with unicode bidi introduced in this code/i, line: 3, endLine: 3, column: 53, endColumn: 54 },
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
tester.run(`${ruleName} in comment-line`, Rule, {
|
|
39
|
+
valid: [
|
|
40
|
+
{
|
|
41
|
+
code: `
|
|
42
|
+
var isAdmin = false;
|
|
43
|
+
/* begin admins only */ if (isAdmin) {
|
|
44
|
+
console.log("You are an admin.");
|
|
45
|
+
/* end admins only */ }
|
|
46
|
+
`,
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
invalid: [
|
|
50
|
+
{
|
|
51
|
+
code: `
|
|
52
|
+
var isAdmin = false;
|
|
53
|
+
/* } if (isAdmin) begin admins only */
|
|
54
|
+
console.log("You are an admin.");
|
|
55
|
+
/* end admins only
|
|
56
|
+
*/
|
|
57
|
+
/* end admins only
|
|
58
|
+
{ */
|
|
59
|
+
`,
|
|
60
|
+
errors: [
|
|
61
|
+
{ message: /Detected potential trojan source attack with unicode bidi introduced in this comment/i, line: 3, endLine: 3, column: 9, endColumn: 10 },
|
|
62
|
+
{ message: /Detected potential trojan source attack with unicode bidi introduced in this comment/i, line: 3, endLine: 3, column: 13, endColumn: 14 },
|
|
63
|
+
{ message: /Detected potential trojan source attack with unicode bidi introduced in this comment/i, line: 3, endLine: 3, column: 26, endColumn: 27 },
|
|
64
|
+
{ message: /Detected potential trojan source attack with unicode bidi introduced in this comment/i, line: 3, endLine: 3, column: 28, endColumn: 29 },
|
|
65
|
+
|
|
66
|
+
{ message: /Detected potential trojan source attack with unicode bidi introduced in this comment/i, line: 5, endLine: 5, column: 26, endColumn: 27 },
|
|
67
|
+
{ message: /Detected potential trojan source attack with unicode bidi introduced in this comment/i, line: 6, endLine: 6, column: 1, endColumn: 2 },
|
|
68
|
+
|
|
69
|
+
{ message: /Detected potential trojan source attack with unicode bidi introduced in this comment/i, line: 7, endLine: 7, column: 26, endColumn: 27 },
|
|
70
|
+
{ message: /Detected potential trojan source attack with unicode bidi introduced in this comment/i, line: 8, endLine: 8, column: 4, endColumn: 5 },
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
});
|
|
@@ -1,25 +1,136 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const RuleTester = require('eslint').RuleTester;
|
|
4
|
-
const tester = new RuleTester(
|
|
4
|
+
const tester = new RuleTester({
|
|
5
|
+
parserOptions: {
|
|
6
|
+
ecmaVersion: 6,
|
|
7
|
+
sourceType: 'module',
|
|
8
|
+
},
|
|
9
|
+
});
|
|
5
10
|
|
|
6
11
|
const ruleName = 'detect-child-process';
|
|
7
12
|
const rule = require(`../rules/${ruleName}`);
|
|
8
13
|
|
|
9
14
|
tester.run(ruleName, rule, {
|
|
10
|
-
valid: [
|
|
15
|
+
valid: [
|
|
16
|
+
"child_process.exec('ls')",
|
|
17
|
+
`
|
|
18
|
+
var {} = require('child_process');
|
|
19
|
+
var result = /hello/.exec(str);`,
|
|
20
|
+
`
|
|
21
|
+
var {} = require('node:child_process');
|
|
22
|
+
var result = /hello/.exec(str);`,
|
|
23
|
+
`
|
|
24
|
+
import {} from 'child_process';
|
|
25
|
+
var result = /hello/.exec(str);`,
|
|
26
|
+
`
|
|
27
|
+
import {} from 'node:child_process';
|
|
28
|
+
var result = /hello/.exec(str);`,
|
|
29
|
+
"var { spawn } = require('child_process'); spawn(str);",
|
|
30
|
+
"var { spawn } = require('node:child_process'); spawn(str);",
|
|
31
|
+
"import { spawn } from 'child_process'; spawn(str);",
|
|
32
|
+
"import { spawn } from 'node:child_process'; spawn(str);",
|
|
33
|
+
`
|
|
34
|
+
var foo = require('child_process');
|
|
35
|
+
function fn () {
|
|
36
|
+
var foo = /hello/;
|
|
37
|
+
var result = foo.exec(str);
|
|
38
|
+
}`,
|
|
39
|
+
"var child = require('child_process'); child.spawn(str)",
|
|
40
|
+
"var child = require('node:child_process'); child.spawn(str)",
|
|
41
|
+
"import child from 'child_process'; child.spawn(str)",
|
|
42
|
+
"import child from 'node:child_process'; child.spawn(str)",
|
|
43
|
+
`
|
|
44
|
+
var foo = require('child_process');
|
|
45
|
+
function fn () {
|
|
46
|
+
var result = foo.spawn(str);
|
|
47
|
+
}`,
|
|
48
|
+
"require('child_process').spawn(str)",
|
|
49
|
+
`
|
|
50
|
+
function fn () {
|
|
51
|
+
require('child_process').spawn(str)
|
|
52
|
+
}`,
|
|
53
|
+
],
|
|
11
54
|
invalid: [
|
|
12
55
|
{
|
|
13
56
|
code: "require('child_process')",
|
|
14
57
|
errors: [{ message: 'Found require("child_process")' }],
|
|
15
58
|
},
|
|
59
|
+
{
|
|
60
|
+
code: "require('node:child_process')",
|
|
61
|
+
errors: [{ message: 'Found require("node:child_process")' }],
|
|
62
|
+
},
|
|
16
63
|
{
|
|
17
64
|
code: "var child = require('child_process'); child.exec(com)",
|
|
18
|
-
errors: [{ message: 'Found
|
|
65
|
+
errors: [{ message: 'Found child_process.exec() with non Literal first argument' }],
|
|
19
66
|
},
|
|
20
67
|
{
|
|
21
|
-
code: "var child = require('child_process'); child.exec()",
|
|
68
|
+
code: "var child = require('node:child_process'); child.exec(com)",
|
|
69
|
+
errors: [{ message: 'Found child_process.exec() with non Literal first argument' }],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
code: "import child from 'child_process'; child.exec(com)",
|
|
73
|
+
errors: [{ message: 'Found child_process.exec() with non Literal first argument' }],
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
code: "import child from 'node:child_process'; child.exec(com)",
|
|
77
|
+
errors: [{ message: 'Found child_process.exec() with non Literal first argument' }],
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
code: "var child = sinon.stub(require('child_process')); child.exec.returns({});",
|
|
22
81
|
errors: [{ message: 'Found require("child_process")' }],
|
|
23
82
|
},
|
|
83
|
+
{
|
|
84
|
+
code: "var child = sinon.stub(require('node:child_process')); child.exec.returns({});",
|
|
85
|
+
errors: [{ message: 'Found require("node:child_process")' }],
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
code: `
|
|
89
|
+
var foo = require('child_process');
|
|
90
|
+
function fn () {
|
|
91
|
+
var result = foo.exec(str);
|
|
92
|
+
}`,
|
|
93
|
+
errors: [{ message: 'Found child_process.exec() with non Literal first argument', line: 4 }],
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
code: `
|
|
97
|
+
import foo from 'child_process';
|
|
98
|
+
function fn () {
|
|
99
|
+
var result = foo.exec(str);
|
|
100
|
+
}`,
|
|
101
|
+
errors: [{ message: 'Found child_process.exec() with non Literal first argument', line: 4 }],
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
code: `
|
|
105
|
+
import foo from 'node:child_process';
|
|
106
|
+
function fn () {
|
|
107
|
+
var result = foo.exec(str);
|
|
108
|
+
}`,
|
|
109
|
+
errors: [{ message: 'Found child_process.exec() with non Literal first argument', line: 4 }],
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
code: `
|
|
113
|
+
require('child_process').exec(str)`,
|
|
114
|
+
errors: [{ message: 'Found child_process.exec() with non Literal first argument', line: 2 }],
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
code: `
|
|
118
|
+
function fn () {
|
|
119
|
+
require('child_process').exec(str)
|
|
120
|
+
}`,
|
|
121
|
+
errors: [{ message: 'Found child_process.exec() with non Literal first argument', line: 3 }],
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
code: `
|
|
125
|
+
const {exec} = require('child_process');
|
|
126
|
+
exec(str)`,
|
|
127
|
+
errors: [{ message: 'Found child_process.exec() with non Literal first argument', line: 3 }],
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
code: `
|
|
131
|
+
const {exec} = require('node:child_process');
|
|
132
|
+
exec(str)`,
|
|
133
|
+
errors: [{ message: 'Found child_process.exec() with non Literal first argument', line: 3 }],
|
|
134
|
+
},
|
|
24
135
|
],
|
|
25
136
|
});
|
|
@@ -6,11 +6,11 @@ const tester = new RuleTester();
|
|
|
6
6
|
const ruleName = 'detect-eval-with-expression';
|
|
7
7
|
|
|
8
8
|
tester.run(ruleName, require(`../rules/${ruleName}`), {
|
|
9
|
-
valid: [{ code:
|
|
9
|
+
valid: [{ code: "eval('alert()')" }],
|
|
10
10
|
invalid: [
|
|
11
11
|
{
|
|
12
12
|
code: 'eval(a);',
|
|
13
|
-
errors: [{ message: 'eval with argument of type Identifier' }]
|
|
14
|
-
}
|
|
15
|
-
]
|
|
13
|
+
errors: [{ message: 'eval with argument of type Identifier' }],
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
16
|
});
|
|
@@ -7,11 +7,11 @@ const ruleName = 'detect-new-buffer';
|
|
|
7
7
|
const invalid = 'var a = new Buffer(c)';
|
|
8
8
|
|
|
9
9
|
tester.run(ruleName, require(`../rules/${ruleName}`), {
|
|
10
|
-
valid: [{ code:
|
|
10
|
+
valid: [{ code: "var a = new Buffer('test')" }],
|
|
11
11
|
invalid: [
|
|
12
12
|
{
|
|
13
13
|
code: invalid,
|
|
14
|
-
errors: [{ message: 'Found new Buffer' }]
|
|
15
|
-
}
|
|
16
|
-
]
|
|
14
|
+
errors: [{ message: 'Found new Buffer' }],
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
17
|
});
|
|
@@ -10,7 +10,7 @@ tester.run(ruleName, require(`../rules/${ruleName}`), {
|
|
|
10
10
|
invalid: [
|
|
11
11
|
{
|
|
12
12
|
code: 'express.csrf();express.methodOverride()',
|
|
13
|
-
errors: [{ message: 'express.csrf() middleware found before express.methodOverride()' }]
|
|
14
|
-
}
|
|
15
|
-
]
|
|
13
|
+
errors: [{ message: 'express.csrf() middleware found before express.methodOverride()' }],
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
16
|
});
|