eslint-plugin-security 1.4.0 → 1.5.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/.eslintrc +11 -1
- package/.github/workflows/ci.yml +47 -0
- package/.github/workflows/pr.yml +15 -0
- package/.prettierrc.json +7 -0
- package/CHANGELOG.md +65 -34
- package/README.md +26 -24
- package/docs/avoid-command-injection-node.md +85 -0
- package/docs/bypass-connect-csrf-protection-by-abusing.md +42 -0
- package/docs/regular-expression-dos-and-node.md +83 -0
- package/docs/the-dangers-of-square-bracket-notation.md +107 -0
- package/index.js +1 -3
- package/package.json +26 -7
- package/rules/data/fsFunctionData.json +49 -49
- package/rules/detect-buffer-noassert.js +66 -55
- package/rules/detect-child-process.js +36 -27
- package/rules/detect-disable-mustache-escape.js +24 -14
- package/rules/detect-eval-with-expression.js +19 -9
- package/rules/detect-new-buffer.js +18 -15
- package/rules/detect-no-csrf-before-method-override.js +32 -25
- package/rules/detect-non-literal-fs-filename.js +38 -33
- package/rules/detect-non-literal-regexp.js +24 -18
- package/rules/detect-non-literal-require.js +25 -17
- package/rules/detect-object-injection.js +61 -59
- package/rules/detect-possible-timing-attacks.js +40 -42
- package/rules/detect-pseudoRandomBytes.js +18 -11
- package/rules/detect-unsafe-regex.js +36 -23
- package/test/detect-buffer-noassert.js +18 -18
- package/test/detect-child-process.js +14 -24
- package/test/detect-disable-mustache-escape.js +0 -1
- package/test/detect-eval-with-expression.js +0 -1
- package/test/detect-new-buffer.js +0 -1
- package/test/detect-no-csrf-before-method-override.js +0 -1
- package/test/detect-non-literal-fs-filename.js +0 -1
- package/test/detect-non-literal-regexp.js +0 -1
- package/test/detect-non-literal-require.js +8 -5
- package/test/detect-object-injection.js +0 -2
- package/test/detect-possible-timing-attacks.js +0 -2
- package/test/detect-pseudoRandomBytes.js +0 -1
- package/test/detect-unsafe-regexp.js +2 -4
- package/.npmignore +0 -1
package/package.json
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-security",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Security rules for eslint",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"changelog": "changelog eslint-plugin-security all > CHANGELOG.md",
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
8
|
+
"release": "npx semantic-release",
|
|
9
|
+
"test": "mocha test/**/*",
|
|
10
|
+
"format": "prettier --write **/*.{md,js,yml}",
|
|
11
|
+
"lint": "eslint .",
|
|
12
|
+
"lint:fix": "eslint --fix .",
|
|
13
|
+
"cont-int": "npm test && npm run lint"
|
|
11
14
|
},
|
|
12
15
|
"repository": {
|
|
13
16
|
"type": "git",
|
|
@@ -24,13 +27,29 @@
|
|
|
24
27
|
"url": "https://github.com/nodesecurity/eslint-plugin-security/issues"
|
|
25
28
|
},
|
|
26
29
|
"homepage": "https://github.com/nodesecurity/eslint-plugin-security#readme",
|
|
30
|
+
"gitHooks": {
|
|
31
|
+
"pre-commit": "lint-staged"
|
|
32
|
+
},
|
|
33
|
+
"lint-staged": {
|
|
34
|
+
"*.js": [
|
|
35
|
+
"prettier --write",
|
|
36
|
+
"eslint --fix"
|
|
37
|
+
],
|
|
38
|
+
"*.md": "prettier --write",
|
|
39
|
+
"*.yml": "prettier --write"
|
|
40
|
+
},
|
|
27
41
|
"dependencies": {
|
|
28
|
-
"safe-regex": "^1.1
|
|
42
|
+
"safe-regex": "^2.1.1"
|
|
29
43
|
},
|
|
30
44
|
"devDependencies": {
|
|
31
45
|
"changelog": "1.3.0",
|
|
32
|
-
"eslint": "^
|
|
46
|
+
"eslint": "^8.11.0",
|
|
33
47
|
"eslint-config-nodesecurity": "^1.3.1",
|
|
34
|
-
"
|
|
48
|
+
"eslint-config-prettier": "^8.5.0",
|
|
49
|
+
"lint-staged": "^12.3.7",
|
|
50
|
+
"mocha": "^9.2.2",
|
|
51
|
+
"prettier": "^2.6.2",
|
|
52
|
+
"semantic-release": "^19.0.2",
|
|
53
|
+
"yorkie": "^2.0.0"
|
|
35
54
|
}
|
|
36
55
|
}
|
|
@@ -1,51 +1,51 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
2
|
+
"appendFile": [0],
|
|
3
|
+
"appendFileSync": [0],
|
|
4
|
+
"chmod": [0],
|
|
5
|
+
"chmodSync": [0],
|
|
6
|
+
"chown": [0],
|
|
7
|
+
"chownSync": [0],
|
|
8
|
+
"createReadStream": [0],
|
|
9
|
+
"createWriteStream": [0],
|
|
10
|
+
"exists": [0],
|
|
11
|
+
"existsSync": [0],
|
|
12
|
+
"lchmod": [0],
|
|
13
|
+
"lchmodSync": [0],
|
|
14
|
+
"lchown": [0],
|
|
15
|
+
"lchownSync": [0],
|
|
16
|
+
"link": [0, 1],
|
|
17
|
+
"linkSync": [0, 1],
|
|
18
|
+
"lstat": [0],
|
|
19
|
+
"lstatSync": [0],
|
|
20
|
+
"mkdir": [0],
|
|
21
|
+
"mkdirSync": [0],
|
|
22
|
+
"open": [0],
|
|
23
|
+
"openSync": [0],
|
|
24
|
+
"readdir": [0],
|
|
25
|
+
"readdirSync": [0],
|
|
26
|
+
"readFile": [0],
|
|
27
|
+
"readFileSync": [0],
|
|
28
|
+
"readlink": [0],
|
|
29
|
+
"readlinkSync": [0],
|
|
30
|
+
"realpath": [0],
|
|
31
|
+
"realpathSync": [0],
|
|
32
|
+
"rename": [0, 1],
|
|
33
|
+
"renameSync": [0, 1],
|
|
34
|
+
"rmdir": [0],
|
|
35
|
+
"rmdirSync": [0],
|
|
36
|
+
"stat": [0],
|
|
37
|
+
"statSync": [0],
|
|
38
|
+
"symlink": [0, 1],
|
|
39
|
+
"symlinkSync": [0, 1],
|
|
40
|
+
"truncate": [0],
|
|
41
|
+
"truncateSync": [0],
|
|
42
|
+
"unlink": [0],
|
|
43
|
+
"unlinkSync": [0],
|
|
44
|
+
"unwatchFile": [0],
|
|
45
|
+
"utimes": [0],
|
|
46
|
+
"utimesSync": [0],
|
|
47
|
+
"watch": [0],
|
|
48
|
+
"watchFile": [0],
|
|
49
|
+
"writeFile": [0],
|
|
50
|
+
"writeFileSync": [0]
|
|
51
51
|
}
|
|
@@ -1,69 +1,80 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tries to detect buffer read / write calls that use noAssert set to true
|
|
3
|
-
* @author Adam Baldwin
|
|
3
|
+
* @author Adam Baldwin
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
// Rule Definition
|
|
8
|
-
//------------------------------------------------------------------------------
|
|
6
|
+
'use strict';
|
|
9
7
|
|
|
10
|
-
|
|
8
|
+
//-----------------------------------------------------------------------------
|
|
9
|
+
// Helpers
|
|
10
|
+
//-----------------------------------------------------------------------------
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
const read = [
|
|
13
|
+
'readUInt8',
|
|
14
|
+
'readUInt16LE',
|
|
15
|
+
'readUInt16BE',
|
|
16
|
+
'readUInt32LE',
|
|
17
|
+
'readUInt32BE',
|
|
18
|
+
'readInt8',
|
|
19
|
+
'readInt16LE',
|
|
20
|
+
'readInt16BE',
|
|
21
|
+
'readInt32LE',
|
|
22
|
+
'readInt32BE',
|
|
23
|
+
'readFloatLE',
|
|
24
|
+
'readFloatBE',
|
|
25
|
+
'readDoubleLE',
|
|
26
|
+
'readDoubleBE',
|
|
27
|
+
];
|
|
13
28
|
|
|
14
|
-
|
|
29
|
+
const write = [
|
|
30
|
+
'writeUInt8',
|
|
31
|
+
'writeUInt16LE',
|
|
32
|
+
'writeUInt16BE',
|
|
33
|
+
'writeUInt32LE',
|
|
34
|
+
'writeUInt32BE',
|
|
35
|
+
'writeInt8',
|
|
36
|
+
'writeInt16LE',
|
|
37
|
+
'writeInt16BE',
|
|
38
|
+
'writeInt32LE',
|
|
39
|
+
'writeInt32BE',
|
|
40
|
+
'writeFloatLE',
|
|
41
|
+
'writeFloatBE',
|
|
42
|
+
'writeDoubleLE',
|
|
43
|
+
'writeDoubleBE',
|
|
44
|
+
];
|
|
15
45
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"readUInt16BE",
|
|
20
|
-
"readUInt32LE",
|
|
21
|
-
"readUInt32BE",
|
|
22
|
-
"readInt8",
|
|
23
|
-
"readInt16LE",
|
|
24
|
-
"readInt16BE",
|
|
25
|
-
"readInt32LE",
|
|
26
|
-
"readInt32BE",
|
|
27
|
-
"readFloatLE",
|
|
28
|
-
"readFloatBE",
|
|
29
|
-
"readDoubleL",
|
|
30
|
-
"readDoubleBE"
|
|
31
|
-
];
|
|
32
|
-
|
|
33
|
-
var write = [
|
|
34
|
-
"writeUInt8",
|
|
35
|
-
"writeUInt16LE",
|
|
36
|
-
"writeUInt16BE",
|
|
37
|
-
"writeUInt32LE",
|
|
38
|
-
"writeUInt32BE",
|
|
39
|
-
"writeInt8",
|
|
40
|
-
"writeInt16LE",
|
|
41
|
-
"writeInt16BE",
|
|
42
|
-
"writeInt32LE",
|
|
43
|
-
"writeInt32BE",
|
|
44
|
-
"writeFloatLE",
|
|
45
|
-
"writeFloatBE",
|
|
46
|
-
"writeDoubleLE",
|
|
47
|
-
"writeDoubleBE"
|
|
48
|
-
];
|
|
46
|
+
//------------------------------------------------------------------------------
|
|
47
|
+
// Rule Definition
|
|
48
|
+
//------------------------------------------------------------------------------
|
|
49
49
|
|
|
50
|
+
module.exports = {
|
|
51
|
+
meta: {
|
|
52
|
+
type: 'error',
|
|
53
|
+
docs: {
|
|
54
|
+
description: 'Detect calls to "buffer" with "noAssert" flag set.',
|
|
55
|
+
category: 'Possible Security Vulnerability',
|
|
56
|
+
recommended: true,
|
|
57
|
+
url: 'https://github.com/nodesecurity/eslint-plugin-security#detect-buffer-noassert',
|
|
58
|
+
},
|
|
59
|
+
__methodsToCheck: {
|
|
60
|
+
read,
|
|
61
|
+
write,
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
create: function (context) {
|
|
50
65
|
return {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (index && node.parent && node.parent.arguments && node.parent.arguments[index] && node.parent.arguments[index].value) {
|
|
60
|
-
var token = context.getTokens(node)[0];
|
|
61
|
-
return context.report(node, 'Found Buffer.' + node.property.name + ' with noAssert flag set true');
|
|
62
|
-
|
|
63
|
-
}
|
|
66
|
+
MemberExpression: function (node) {
|
|
67
|
+
let index;
|
|
68
|
+
if (read.indexOf(node.property.name) !== -1) {
|
|
69
|
+
index = 1;
|
|
70
|
+
} else if (write.indexOf(node.property.name) !== -1) {
|
|
71
|
+
index = 2;
|
|
64
72
|
}
|
|
65
73
|
|
|
74
|
+
if (index && node.parent && node.parent.arguments && node.parent.arguments[index] && node.parent.arguments[index].value) {
|
|
75
|
+
return context.report(node, `Found Buffer.${node.property.name} with noAssert flag set true`);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
66
78
|
};
|
|
67
|
-
|
|
79
|
+
},
|
|
68
80
|
};
|
|
69
|
-
|
|
@@ -3,40 +3,49 @@
|
|
|
3
3
|
* @author Adam Baldwin
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
6
8
|
//------------------------------------------------------------------------------
|
|
7
9
|
// Rule Definition
|
|
8
10
|
//------------------------------------------------------------------------------
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"use strict";
|
|
12
|
+
/*
|
|
13
|
+
* Stores variable names pointing to child_process to check (child_process).exec()
|
|
14
|
+
*/
|
|
15
|
+
const names = [];
|
|
15
16
|
|
|
17
|
+
module.exports = {
|
|
18
|
+
meta: {
|
|
19
|
+
type: 'error',
|
|
20
|
+
docs: {
|
|
21
|
+
description: 'Detect instances of "child_process" & non-literal "exec()" calls.',
|
|
22
|
+
category: 'Possible Security Vulnerability',
|
|
23
|
+
recommended: true,
|
|
24
|
+
url: 'https://github.com/nodesecurity/eslint-plugin-security/blob/main/docs/avoid-command-injection-node.md',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
create: function (context) {
|
|
16
28
|
return {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
names.push(node.parent.left.name);
|
|
26
|
-
}
|
|
27
|
-
return context.report(node, 'Found require("child_process")');
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
"MemberExpression": function (node) {
|
|
32
|
-
var token = context.getTokens(node)[0];
|
|
33
|
-
if (node.property.name === 'exec' && names.indexOf(node.object.name) > -1) {
|
|
34
|
-
if (node.parent && node.parent.arguments && node.parent.arguments[0].type !== 'Literal') {
|
|
35
|
-
return context.report(node, 'Found child_process.exec() with non Literal first argument');
|
|
36
|
-
}
|
|
29
|
+
CallExpression: function (node) {
|
|
30
|
+
if (node.callee.name === 'require') {
|
|
31
|
+
const args = node.arguments[0];
|
|
32
|
+
if (args && args.type === 'Literal' && args.value === 'child_process') {
|
|
33
|
+
if (node.parent.type === 'VariableDeclarator') {
|
|
34
|
+
names.push(node.parent.id.name);
|
|
35
|
+
} else if (node.parent.type === 'AssignmentExpression' && node.parent.operator === '=') {
|
|
36
|
+
names.push(node.parent.left.name);
|
|
37
37
|
}
|
|
38
|
+
return context.report(node, 'Found require("child_process")');
|
|
39
|
+
}
|
|
38
40
|
}
|
|
39
|
-
|
|
41
|
+
},
|
|
42
|
+
MemberExpression: function (node) {
|
|
43
|
+
if (node.property.name === 'exec' && names.indexOf(node.object.name) > -1) {
|
|
44
|
+
if (node.parent && node.parent.arguments.length && node.parent.arguments[0].type !== 'Literal') {
|
|
45
|
+
return context.report(node, 'Found child_process.exec() with non Literal first argument');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
40
49
|
};
|
|
41
|
-
|
|
50
|
+
},
|
|
42
51
|
};
|
|
@@ -1,18 +1,28 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
module.exports = {
|
|
4
|
+
meta: {
|
|
5
|
+
type: 'error',
|
|
6
|
+
docs: {
|
|
7
|
+
description: 'Detects "object.escapeMarkup = false", which can be used with some template engines to disable escaping of HTML entities.',
|
|
8
|
+
category: 'Possible Security Vulnerability',
|
|
9
|
+
recommended: true,
|
|
10
|
+
url: 'https://github.com/nodesecurity/eslint-plugin-security#detect-disable-mustache-escape'
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
create: function (context) {
|
|
4
14
|
return {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
}
|
|
15
|
+
AssignmentExpression: function (node) {
|
|
16
|
+
if (node.operator === '=') {
|
|
17
|
+
if (node.left.property) {
|
|
18
|
+
if (node.left.property.name === 'escapeMarkup') {
|
|
19
|
+
if (node.right.value === false) {
|
|
20
|
+
context.report(node, 'Markup escaping disabled.');
|
|
21
|
+
}
|
|
14
22
|
}
|
|
23
|
+
}
|
|
15
24
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
};
|
|
@@ -1,21 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Identifies eval with expression
|
|
3
3
|
* @author Adam Baldwin
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
6
8
|
//------------------------------------------------------------------------------
|
|
7
9
|
// Rule Definition
|
|
8
10
|
//------------------------------------------------------------------------------
|
|
9
11
|
|
|
10
|
-
module.exports =
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
module.exports = {
|
|
13
|
+
meta: {
|
|
14
|
+
type: 'error',
|
|
15
|
+
docs: {
|
|
16
|
+
description: 'Detects "eval(variable)" which can allow an attacker to run arbitrary code inside your process.',
|
|
17
|
+
category: 'Possible Security Vulnerability',
|
|
18
|
+
recommended: true,
|
|
19
|
+
url: 'https://github.com/nodesecurity/eslint-plugin-security#detect-eval-with-expression'
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
create: function (context) {
|
|
14
23
|
return {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
24
|
+
CallExpression: function (node) {
|
|
25
|
+
if (node.callee.name === 'eval' && node.arguments[0].type !== 'Literal') {
|
|
26
|
+
context.report(node, `eval with argument of type ${node.arguments[0].type}`);
|
|
19
27
|
}
|
|
28
|
+
}
|
|
20
29
|
};
|
|
30
|
+
}
|
|
21
31
|
};
|
|
@@ -1,19 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
// Detects instances of new Buffer(argument)
|
|
3
|
-
// where argument is any non literal value.
|
|
4
|
-
return {
|
|
5
|
-
"NewExpression": function (node) {
|
|
6
|
-
if (node.callee.name === 'Buffer' &&
|
|
7
|
-
node.arguments[0] &&
|
|
8
|
-
node.arguments[0].type != 'Literal') {
|
|
1
|
+
'use strict';
|
|
9
2
|
|
|
10
|
-
|
|
3
|
+
module.exports = {
|
|
4
|
+
meta: {
|
|
5
|
+
type: 'error',
|
|
6
|
+
docs: {
|
|
7
|
+
description: 'Detect instances of new Buffer(argument) where argument is any non-literal value.',
|
|
8
|
+
category: 'Possible Security Vulnerability',
|
|
9
|
+
recommended: true,
|
|
10
|
+
url: 'https://github.com/nodesecurity/eslint-plugin-security/blob/main/README.md'
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
create: function (context) {
|
|
14
|
+
return {
|
|
15
|
+
NewExpression: function (node) {
|
|
16
|
+
if (node.callee.name === 'Buffer' && node.arguments[0] && node.arguments[0].type !== 'Literal') {
|
|
17
|
+
return context.report(node, 'Found new Buffer');
|
|
11
18
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
19
|
}
|
|
16
20
|
};
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
|
|
21
|
+
}
|
|
22
|
+
};
|
|
@@ -3,37 +3,44 @@
|
|
|
3
3
|
* @author Adam Baldwin
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
6
8
|
//------------------------------------------------------------------------------
|
|
7
9
|
// Rule Definition
|
|
8
10
|
//------------------------------------------------------------------------------
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
module.exports = {
|
|
13
|
+
meta: {
|
|
14
|
+
type: 'error',
|
|
15
|
+
docs: {
|
|
16
|
+
description: 'Detects Express "csrf" middleware setup before "method-override" middleware.',
|
|
17
|
+
category: 'Possible Security Vulnerability',
|
|
18
|
+
recommended: true,
|
|
19
|
+
url: 'https://github.com/nodesecurity/eslint-plugin-security/blob/main/docs/bypass-connect-csrf-protection-by-abusing.md',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
create: function (context) {
|
|
23
|
+
let csrf = false;
|
|
15
24
|
|
|
16
25
|
return {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
}
|
|
26
|
+
CallExpression: function (node) {
|
|
27
|
+
const token = context.getTokens(node)[0];
|
|
28
|
+
const nodeValue = token.value;
|
|
29
|
+
|
|
30
|
+
if (nodeValue === 'express') {
|
|
31
|
+
if (!node.callee || !node.callee.property) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (node.callee.property.name === 'methodOverride' && csrf) {
|
|
36
|
+
context.report(node, 'express.csrf() middleware found before express.methodOverride()');
|
|
37
|
+
}
|
|
38
|
+
if (node.callee.property.name === 'csrf') {
|
|
39
|
+
// Keep track of found CSRF
|
|
40
|
+
csrf = true;
|
|
41
|
+
}
|
|
35
42
|
}
|
|
43
|
+
},
|
|
36
44
|
};
|
|
37
|
-
|
|
45
|
+
},
|
|
38
46
|
};
|
|
39
|
-
|
|
@@ -3,47 +3,52 @@
|
|
|
3
3
|
* @author Adam Baldwin
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
6
8
|
//------------------------------------------------------------------------------
|
|
7
9
|
// Rule Definition
|
|
8
10
|
//------------------------------------------------------------------------------
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
const fsMetaData = require('./data/fsFunctionData.json');
|
|
13
|
+
const funcNames = Object.keys(fsMetaData);
|
|
14
|
+
|
|
15
|
+
module.exports = {
|
|
16
|
+
meta: {
|
|
17
|
+
type: 'error',
|
|
18
|
+
docs: {
|
|
19
|
+
description: 'Detects variable in filename argument of "fs" calls, which might allow an attacker to access anything on your system.',
|
|
20
|
+
category: 'Possible Security Vulnerability',
|
|
21
|
+
recommended: true,
|
|
22
|
+
url: 'https://github.com/nodesecurity/eslint-plugin-security#detect-non-literal-fs-filename',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
create: function (context) {
|
|
18
26
|
return {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (result.length > 0) {
|
|
34
|
-
var token = context.getTokens(node)[0];
|
|
35
|
-
return context.report(node, 'Found fs.' + node.property.name + ' with non literal argument at index ' + result.join(','));
|
|
27
|
+
MemberExpression: function (node) {
|
|
28
|
+
const result = [];
|
|
29
|
+
if (funcNames.indexOf(node.property.name) !== -1) {
|
|
30
|
+
const meta = fsMetaData[node.property.name];
|
|
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
|
+
}
|
|
36
37
|
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (node.parent && node.parent.arguments && node.parent.arguments[index].value) {
|
|
41
|
-
return context.report(node, 'found Buffer.' + node.property.name + ' with noAssert flag set true');
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
*/
|
|
41
|
+
if (result.length > 0) {
|
|
42
|
+
return context.report(node, `Found fs.${node.property.name} with non literal argument at index ${result.join(',')}`);
|
|
45
43
|
}
|
|
46
44
|
|
|
47
|
-
|
|
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');
|
|
48
48
|
|
|
49
|
+
}
|
|
50
|
+
*/
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
},
|
|
49
54
|
};
|