eslint-plugin-secure-coding 2.2.5 → 2.2.7
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/CHANGELOG.md +11 -0
- package/package.json +7 -7
- package/src/rules/detect-child-process/index.js +5 -5
- package/src/rules/detect-child-process/index.js.map +1 -1
- package/src/rules/detect-non-literal-fs-filename/index.js +36 -21
- package/src/rules/detect-non-literal-fs-filename/index.js.map +1 -1
- package/src/rules/detect-object-injection/index.js +71 -28
- package/src/rules/detect-object-injection/index.js.map +1 -1
- package/src/rules/no-arbitrary-file-access/index.d.ts +7 -0
- package/src/rules/no-arbitrary-file-access/index.js +135 -2
- package/src/rules/no-arbitrary-file-access/index.js.map +1 -1
- package/src/rules/no-buffer-overread/index.d.ts +16 -1
- package/src/rules/no-buffer-overread/index.js +94 -83
- package/src/rules/no-buffer-overread/index.js.map +1 -1
- package/src/rules/no-missing-csrf-protection/index.js +7 -11
- package/src/rules/no-missing-csrf-protection/index.js.map +1 -1
- package/src/rules/no-password-in-url/index.js +0 -1
- package/src/rules/no-password-in-url/index.js.map +1 -1
- package/src/rules/no-permissive-cors/index.js +3 -4
- package/src/rules/no-permissive-cors/index.js.map +1 -1
- package/src/rules/no-pii-in-logs/index.js +0 -1
- package/src/rules/no-pii-in-logs/index.js.map +1 -1
- package/src/rules/no-postmessage-origin-wildcard/index.js +0 -1
- package/src/rules/no-postmessage-origin-wildcard/index.js.map +1 -1
- package/src/rules/no-privilege-escalation/index.js +3 -5
- package/src/rules/no-privilege-escalation/index.js.map +1 -1
- package/src/rules/no-timing-attack/index.js +32 -17
- package/src/rules/no-timing-attack/index.js.map +1 -1
- package/src/rules/no-unencrypted-local-storage/index.js +0 -1
- package/src/rules/no-unencrypted-local-storage/index.js.map +1 -1
- package/src/rules/no-unsafe-deserialization/index.js +33 -43
- package/src/rules/no-unsafe-deserialization/index.js.map +1 -1
- package/src/rules/no-unvalidated-user-input/index.d.ts +1 -1
- package/src/rules/no-unvalidated-user-input/index.js +18 -15
- package/src/rules/no-unvalidated-user-input/index.js.map +1 -1
- package/src/rules/no-verbose-error-messages/index.js +12 -11
- package/src/rules/no-verbose-error-messages/index.js.map +1 -1
- package/src/rules/no-weak-password-recovery/index.js +24 -13
- package/src/rules/no-weak-password-recovery/index.js.map +1 -1
- package/src/rules/require-https-only/index.js +0 -1
- package/src/rules/require-https-only/index.js.map +1 -1
- package/src/rules/require-mime-type-validation/index.js +7 -7
- package/src/rules/require-mime-type-validation/index.js.map +1 -1
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* @fileoverview Prevent file access from user input
|
|
4
|
+
*
|
|
5
|
+
* False Positive Reduction:
|
|
6
|
+
* This rule detects safe patterns including:
|
|
7
|
+
* - path.basename() sanitization
|
|
8
|
+
* - path.join() with validated base directories
|
|
9
|
+
* - startsWith() validation guards
|
|
10
|
+
* - Early-return throw patterns
|
|
4
11
|
*/
|
|
5
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
13
|
exports.noArbitraryFileAccess = void 0;
|
|
@@ -27,13 +34,130 @@ exports.noArbitraryFileAccess = (0, eslint_devkit_1.createRule)({
|
|
|
27
34
|
},
|
|
28
35
|
defaultOptions: [],
|
|
29
36
|
create(context) {
|
|
37
|
+
const sourceCode = context.sourceCode;
|
|
30
38
|
function report(node) {
|
|
31
39
|
context.report({ node, messageId: 'violationDetected' });
|
|
32
40
|
}
|
|
33
41
|
const fsReadMethods = ['readFile', 'readFileSync', 'readdir', 'readdirSync', 'stat', 'statSync'];
|
|
34
42
|
const fsWriteMethods = ['writeFile', 'writeFileSync', 'appendFile', 'appendFileSync'];
|
|
35
43
|
const userInputSources = ['req', 'request', 'params', 'query', 'body'];
|
|
44
|
+
// Track variables that have been sanitized with path.basename()
|
|
45
|
+
const sanitizedVariables = new Set();
|
|
46
|
+
// Track variables that have been validated with startsWith() guards
|
|
47
|
+
const validatedVariables = new Set();
|
|
48
|
+
/**
|
|
49
|
+
* Check if a variable is assigned from path.basename() or path.join() with basename
|
|
50
|
+
*/
|
|
51
|
+
function checkVariableDeclaration(node) {
|
|
52
|
+
if (node.id.type !== 'Identifier' || !node.init) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const varName = node.id.name;
|
|
56
|
+
const init = node.init;
|
|
57
|
+
// Check for path.basename() assignment
|
|
58
|
+
if (init.type === 'CallExpression' &&
|
|
59
|
+
init.callee.type === 'MemberExpression' &&
|
|
60
|
+
init.callee.object.type === 'Identifier' &&
|
|
61
|
+
init.callee.object.name === 'path' &&
|
|
62
|
+
init.callee.property.type === 'Identifier' &&
|
|
63
|
+
init.callee.property.name === 'basename') {
|
|
64
|
+
sanitizedVariables.add(varName);
|
|
65
|
+
}
|
|
66
|
+
// Check for path.join() with a sanitized variable or literal base
|
|
67
|
+
if (init.type === 'CallExpression' &&
|
|
68
|
+
init.callee.type === 'MemberExpression' &&
|
|
69
|
+
init.callee.object.type === 'Identifier' &&
|
|
70
|
+
init.callee.object.name === 'path' &&
|
|
71
|
+
init.callee.property.type === 'Identifier' &&
|
|
72
|
+
init.callee.property.name === 'join') {
|
|
73
|
+
// Check if any argument is a sanitized variable
|
|
74
|
+
const hasSanitizedArg = init.arguments.some((arg) => arg.type === 'Identifier' && sanitizedVariables.has(arg.name));
|
|
75
|
+
// Check if first arg is a safe base (literal or known safe variable)
|
|
76
|
+
const firstArg = init.arguments[0];
|
|
77
|
+
const hasSafeBase = firstArg && (firstArg.type === 'Literal' ||
|
|
78
|
+
(firstArg.type === 'Identifier' && /^(SAFE|BASE|ROOT|UPLOAD|PUBLIC)/i.test(firstArg.name)));
|
|
79
|
+
if (hasSanitizedArg && hasSafeBase) {
|
|
80
|
+
sanitizedVariables.add(varName);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Check if there's a startsWith() guard validation for this variable
|
|
86
|
+
* Looks for patterns like:
|
|
87
|
+
* if (!path.startsWith(baseDir)) { throw ... }
|
|
88
|
+
* if (!path.startsWith(baseDir)) { return ... }
|
|
89
|
+
*/
|
|
90
|
+
function hasStartsWithGuard(node, varName) {
|
|
91
|
+
// Already validated
|
|
92
|
+
if (validatedVariables.has(varName)) {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
// Walk up to find the containing block or function
|
|
96
|
+
let current = node.parent;
|
|
97
|
+
while (current) {
|
|
98
|
+
// If we've reached a function body or block, search its statements
|
|
99
|
+
if (current.type === eslint_devkit_1.AST_NODE_TYPES.BlockStatement) {
|
|
100
|
+
const statements = current.body;
|
|
101
|
+
// Look for IF statements in this block that validate our variable
|
|
102
|
+
for (const stmt of statements) {
|
|
103
|
+
if (stmt.type === eslint_devkit_1.AST_NODE_TYPES.IfStatement) {
|
|
104
|
+
const testText = sourceCode.getText(stmt.test).toLowerCase();
|
|
105
|
+
// Check for startsWith() validation pattern with our variable
|
|
106
|
+
if (testText.includes('startswith') && testText.includes(varName.toLowerCase())) {
|
|
107
|
+
// Check if this is a guard clause (negated condition with throw/return)
|
|
108
|
+
const consequent = stmt.consequent;
|
|
109
|
+
// Handle block statement: if (...) { throw/return; }
|
|
110
|
+
if (consequent.type === eslint_devkit_1.AST_NODE_TYPES.BlockStatement && consequent.body.length > 0) {
|
|
111
|
+
const firstStmt = consequent.body[0];
|
|
112
|
+
if (firstStmt.type === eslint_devkit_1.AST_NODE_TYPES.ThrowStatement || firstStmt.type === eslint_devkit_1.AST_NODE_TYPES.ReturnStatement) {
|
|
113
|
+
validatedVariables.add(varName);
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Handle direct statement: if (...) throw/return;
|
|
118
|
+
if (consequent.type === eslint_devkit_1.AST_NODE_TYPES.ThrowStatement || consequent.type === eslint_devkit_1.AST_NODE_TYPES.ReturnStatement) {
|
|
119
|
+
validatedVariables.add(varName);
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Also check if current IS an if statement (when node is inside the consequent)
|
|
127
|
+
if (current.type === eslint_devkit_1.AST_NODE_TYPES.IfStatement) {
|
|
128
|
+
const testText = sourceCode.getText(current.test).toLowerCase();
|
|
129
|
+
if (testText.includes('startswith') && testText.includes(varName.toLowerCase())) {
|
|
130
|
+
validatedVariables.add(varName);
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
current = current.parent;
|
|
135
|
+
}
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Check if a variable comes from a sanitized/validated source
|
|
140
|
+
*/
|
|
141
|
+
function isVariableSafe(varName, node) {
|
|
142
|
+
// Already tracked as sanitized
|
|
143
|
+
if (sanitizedVariables.has(varName)) {
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
// Has startsWith guard validation
|
|
147
|
+
if (hasStartsWithGuard(node, varName)) {
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
// Check naming conventions that suggest safety
|
|
151
|
+
if (/^(safe|sanitized|validated|clean)/i.test(varName)) {
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
36
156
|
return {
|
|
157
|
+
// Track variable declarations for sanitization patterns
|
|
158
|
+
VariableDeclarator(node) {
|
|
159
|
+
checkVariableDeclaration(node);
|
|
160
|
+
},
|
|
37
161
|
CallExpression(node) {
|
|
38
162
|
// Detect fs.* with user input
|
|
39
163
|
if (node.callee.type === 'MemberExpression' &&
|
|
@@ -42,10 +166,19 @@ exports.noArbitraryFileAccess = (0, eslint_devkit_1.createRule)({
|
|
|
42
166
|
node.callee.property.type === 'Identifier' &&
|
|
43
167
|
[...fsReadMethods, ...fsWriteMethods].includes(node.callee.property.name)) {
|
|
44
168
|
const pathArg = node.arguments[0];
|
|
45
|
-
//
|
|
169
|
+
// Skip if path is a literal (safe)
|
|
170
|
+
if (pathArg && pathArg.type === 'Literal') {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
// Check if path is a variable
|
|
46
174
|
if (pathArg && pathArg.type === 'Identifier') {
|
|
175
|
+
const varName = pathArg.name;
|
|
176
|
+
// Skip if variable is sanitized or validated
|
|
177
|
+
if (isVariableSafe(varName, node)) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
47
180
|
report(node);
|
|
48
|
-
return;
|
|
181
|
+
return;
|
|
49
182
|
}
|
|
50
183
|
// Flag if path is from a member expression (user input sources)
|
|
51
184
|
if (pathArg?.type === 'MemberExpression' &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-secure-coding/src/rules/no-arbitrary-file-access/index.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-secure-coding/src/rules/no-arbitrary-file-access/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* ESLint Rule: no-buffer-overread
|
|
3
|
+
* Detects buffer access beyond bounds (CWE-126)
|
|
4
|
+
*
|
|
5
|
+
* Buffer overread occurs when reading from buffers beyond their allocated
|
|
6
|
+
* length, potentially leading to information disclosure, crashes, or
|
|
7
|
+
* other security issues.
|
|
8
|
+
*
|
|
9
|
+
* False Positive Reduction:
|
|
10
|
+
* This rule uses security utilities to reduce false positives by detecting:
|
|
11
|
+
* - Safe buffer access patterns
|
|
12
|
+
* - Bounds checking operations
|
|
13
|
+
* - JSDoc annotations (@safe, @validated)
|
|
14
|
+
* - Input validation functions
|
|
15
|
+
*/
|
|
16
|
+
import type { SecurityRuleOptions } from '@interlace/eslint-devkit';
|
|
2
17
|
export interface Options extends SecurityRuleOptions {
|
|
3
18
|
/** Buffer methods to check for bounds safety */
|
|
4
19
|
bufferMethods?: string[];
|