eslint-plugin-secure-coding 1.0.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/AGENTS.md +196 -0
- package/CHANGELOG.md +105 -0
- package/LICENSE +23 -0
- package/README.md +377 -0
- package/package.json +80 -0
- package/src/index.d.ts +32 -0
- package/src/index.js +345 -0
- package/src/index.js.map +1 -0
- package/src/rules/security/database-injection.d.ts +13 -0
- package/src/rules/security/database-injection.js +407 -0
- package/src/rules/security/database-injection.js.map +1 -0
- package/src/rules/security/detect-child-process.d.ts +11 -0
- package/src/rules/security/detect-child-process.js +460 -0
- package/src/rules/security/detect-child-process.js.map +1 -0
- package/src/rules/security/detect-eval-with-expression.d.ts +9 -0
- package/src/rules/security/detect-eval-with-expression.js +393 -0
- package/src/rules/security/detect-eval-with-expression.js.map +1 -0
- package/src/rules/security/detect-non-literal-fs-filename.d.ts +7 -0
- package/src/rules/security/detect-non-literal-fs-filename.js +322 -0
- package/src/rules/security/detect-non-literal-fs-filename.js.map +1 -0
- package/src/rules/security/detect-non-literal-regexp.d.ts +9 -0
- package/src/rules/security/detect-non-literal-regexp.js +387 -0
- package/src/rules/security/detect-non-literal-regexp.js.map +1 -0
- package/src/rules/security/detect-object-injection.d.ts +11 -0
- package/src/rules/security/detect-object-injection.js +411 -0
- package/src/rules/security/detect-object-injection.js.map +1 -0
- package/src/rules/security/no-buffer-overread.d.ts +14 -0
- package/src/rules/security/no-buffer-overread.js +519 -0
- package/src/rules/security/no-buffer-overread.js.map +1 -0
- package/src/rules/security/no-clickjacking.d.ts +10 -0
- package/src/rules/security/no-clickjacking.js +381 -0
- package/src/rules/security/no-clickjacking.js.map +1 -0
- package/src/rules/security/no-directive-injection.d.ts +12 -0
- package/src/rules/security/no-directive-injection.js +446 -0
- package/src/rules/security/no-directive-injection.js.map +1 -0
- package/src/rules/security/no-document-cookie.d.ts +5 -0
- package/src/rules/security/no-document-cookie.js +90 -0
- package/src/rules/security/no-document-cookie.js.map +1 -0
- package/src/rules/security/no-electron-security-issues.d.ts +10 -0
- package/src/rules/security/no-electron-security-issues.js +421 -0
- package/src/rules/security/no-electron-security-issues.js.map +1 -0
- package/src/rules/security/no-exposed-sensitive-data.d.ts +11 -0
- package/src/rules/security/no-exposed-sensitive-data.js +341 -0
- package/src/rules/security/no-exposed-sensitive-data.js.map +1 -0
- package/src/rules/security/no-format-string-injection.d.ts +17 -0
- package/src/rules/security/no-format-string-injection.js +653 -0
- package/src/rules/security/no-format-string-injection.js.map +1 -0
- package/src/rules/security/no-graphql-injection.d.ts +12 -0
- package/src/rules/security/no-graphql-injection.js +410 -0
- package/src/rules/security/no-graphql-injection.js.map +1 -0
- package/src/rules/security/no-hardcoded-credentials.d.ts +26 -0
- package/src/rules/security/no-hardcoded-credentials.js +377 -0
- package/src/rules/security/no-hardcoded-credentials.js.map +1 -0
- package/src/rules/security/no-improper-sanitization.d.ts +12 -0
- package/src/rules/security/no-improper-sanitization.js +408 -0
- package/src/rules/security/no-improper-sanitization.js.map +1 -0
- package/src/rules/security/no-improper-type-validation.d.ts +10 -0
- package/src/rules/security/no-improper-type-validation.js +420 -0
- package/src/rules/security/no-improper-type-validation.js.map +1 -0
- package/src/rules/security/no-insecure-comparison.d.ts +7 -0
- package/src/rules/security/no-insecure-comparison.js +125 -0
- package/src/rules/security/no-insecure-comparison.js.map +1 -0
- package/src/rules/security/no-insecure-cookie-settings.d.ts +9 -0
- package/src/rules/security/no-insecure-cookie-settings.js +305 -0
- package/src/rules/security/no-insecure-cookie-settings.js.map +1 -0
- package/src/rules/security/no-insecure-jwt.d.ts +10 -0
- package/src/rules/security/no-insecure-jwt.js +338 -0
- package/src/rules/security/no-insecure-jwt.js.map +1 -0
- package/src/rules/security/no-insecure-redirects.d.ts +7 -0
- package/src/rules/security/no-insecure-redirects.js +215 -0
- package/src/rules/security/no-insecure-redirects.js.map +1 -0
- package/src/rules/security/no-insufficient-postmessage-validation.d.ts +14 -0
- package/src/rules/security/no-insufficient-postmessage-validation.js +390 -0
- package/src/rules/security/no-insufficient-postmessage-validation.js.map +1 -0
- package/src/rules/security/no-insufficient-random.d.ts +9 -0
- package/src/rules/security/no-insufficient-random.js +207 -0
- package/src/rules/security/no-insufficient-random.js.map +1 -0
- package/src/rules/security/no-ldap-injection.d.ts +10 -0
- package/src/rules/security/no-ldap-injection.js +449 -0
- package/src/rules/security/no-ldap-injection.js.map +1 -0
- package/src/rules/security/no-missing-authentication.d.ts +13 -0
- package/src/rules/security/no-missing-authentication.js +322 -0
- package/src/rules/security/no-missing-authentication.js.map +1 -0
- package/src/rules/security/no-missing-cors-check.d.ts +9 -0
- package/src/rules/security/no-missing-cors-check.js +449 -0
- package/src/rules/security/no-missing-cors-check.js.map +1 -0
- package/src/rules/security/no-missing-csrf-protection.d.ts +11 -0
- package/src/rules/security/no-missing-csrf-protection.js +183 -0
- package/src/rules/security/no-missing-csrf-protection.js.map +1 -0
- package/src/rules/security/no-missing-security-headers.d.ts +7 -0
- package/src/rules/security/no-missing-security-headers.js +217 -0
- package/src/rules/security/no-missing-security-headers.js.map +1 -0
- package/src/rules/security/no-privilege-escalation.d.ts +13 -0
- package/src/rules/security/no-privilege-escalation.js +321 -0
- package/src/rules/security/no-privilege-escalation.js.map +1 -0
- package/src/rules/security/no-redos-vulnerable-regex.d.ts +7 -0
- package/src/rules/security/no-redos-vulnerable-regex.js +307 -0
- package/src/rules/security/no-redos-vulnerable-regex.js.map +1 -0
- package/src/rules/security/no-sensitive-data-exposure.d.ts +11 -0
- package/src/rules/security/no-sensitive-data-exposure.js +251 -0
- package/src/rules/security/no-sensitive-data-exposure.js.map +1 -0
- package/src/rules/security/no-sql-injection.d.ts +10 -0
- package/src/rules/security/no-sql-injection.js +332 -0
- package/src/rules/security/no-sql-injection.js.map +1 -0
- package/src/rules/security/no-timing-attack.d.ts +10 -0
- package/src/rules/security/no-timing-attack.js +358 -0
- package/src/rules/security/no-timing-attack.js.map +1 -0
- package/src/rules/security/no-toctou-vulnerability.d.ts +7 -0
- package/src/rules/security/no-toctou-vulnerability.js +165 -0
- package/src/rules/security/no-toctou-vulnerability.js.map +1 -0
- package/src/rules/security/no-unchecked-loop-condition.d.ts +12 -0
- package/src/rules/security/no-unchecked-loop-condition.js +635 -0
- package/src/rules/security/no-unchecked-loop-condition.js.map +1 -0
- package/src/rules/security/no-unencrypted-transmission.d.ts +11 -0
- package/src/rules/security/no-unencrypted-transmission.js +237 -0
- package/src/rules/security/no-unencrypted-transmission.js.map +1 -0
- package/src/rules/security/no-unescaped-url-parameter.d.ts +9 -0
- package/src/rules/security/no-unescaped-url-parameter.js +266 -0
- package/src/rules/security/no-unescaped-url-parameter.js.map +1 -0
- package/src/rules/security/no-unlimited-resource-allocation.d.ts +12 -0
- package/src/rules/security/no-unlimited-resource-allocation.js +659 -0
- package/src/rules/security/no-unlimited-resource-allocation.js.map +1 -0
- package/src/rules/security/no-unsafe-deserialization.d.ts +10 -0
- package/src/rules/security/no-unsafe-deserialization.js +501 -0
- package/src/rules/security/no-unsafe-deserialization.js.map +1 -0
- package/src/rules/security/no-unsafe-dynamic-require.d.ts +5 -0
- package/src/rules/security/no-unsafe-dynamic-require.js +107 -0
- package/src/rules/security/no-unsafe-dynamic-require.js.map +1 -0
- package/src/rules/security/no-unsafe-regex-construction.d.ts +9 -0
- package/src/rules/security/no-unsafe-regex-construction.js +292 -0
- package/src/rules/security/no-unsafe-regex-construction.js.map +1 -0
- package/src/rules/security/no-unsanitized-html.d.ts +9 -0
- package/src/rules/security/no-unsanitized-html.js +347 -0
- package/src/rules/security/no-unsanitized-html.js.map +1 -0
- package/src/rules/security/no-unvalidated-user-input.d.ts +9 -0
- package/src/rules/security/no-unvalidated-user-input.js +418 -0
- package/src/rules/security/no-unvalidated-user-input.js.map +1 -0
- package/src/rules/security/no-weak-crypto.d.ts +11 -0
- package/src/rules/security/no-weak-crypto.js +350 -0
- package/src/rules/security/no-weak-crypto.js.map +1 -0
- package/src/rules/security/no-weak-password-recovery.d.ts +12 -0
- package/src/rules/security/no-weak-password-recovery.js +401 -0
- package/src/rules/security/no-weak-password-recovery.js.map +1 -0
- package/src/rules/security/no-xpath-injection.d.ts +10 -0
- package/src/rules/security/no-xpath-injection.js +487 -0
- package/src/rules/security/no-xpath-injection.js.map +1 -0
- package/src/rules/security/no-xxe-injection.d.ts +7 -0
- package/src/rules/security/no-xxe-injection.js +270 -0
- package/src/rules/security/no-xxe-injection.js.map +1 -0
- package/src/rules/security/no-zip-slip.d.ts +9 -0
- package/src/rules/security/no-zip-slip.js +446 -0
- package/src/rules/security/no-zip-slip.js.map +1 -0
- package/src/types/index.d.ts +131 -0
- package/src/types/index.js +18 -0
- package/src/types/index.js.map +1 -0
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.detectObjectInjection = void 0;
|
|
4
|
+
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
5
|
+
const eslint_devkit_2 = require("@interlace/eslint-devkit");
|
|
6
|
+
const OBJECT_INJECTION_PATTERNS = [
|
|
7
|
+
{
|
|
8
|
+
pattern: '__proto__',
|
|
9
|
+
dangerous: true,
|
|
10
|
+
vulnerability: 'prototype-pollution',
|
|
11
|
+
safeAlternative: 'Object.create(null) or Map',
|
|
12
|
+
example: {
|
|
13
|
+
bad: 'obj[userInput] = value; // if userInput is "__proto__"',
|
|
14
|
+
good: 'const map = new Map(); map.set(userInput, value);'
|
|
15
|
+
},
|
|
16
|
+
effort: '15-20 minutes',
|
|
17
|
+
riskLevel: 'critical'
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
pattern: 'prototype',
|
|
21
|
+
dangerous: true,
|
|
22
|
+
vulnerability: 'prototype-pollution',
|
|
23
|
+
safeAlternative: 'Avoid prototype manipulation',
|
|
24
|
+
example: {
|
|
25
|
+
bad: 'obj[userInput] = value; // if userInput is "prototype"',
|
|
26
|
+
good: 'if (!obj.hasOwnProperty(userInput)) obj[userInput] = value;'
|
|
27
|
+
},
|
|
28
|
+
effort: '10-15 minutes',
|
|
29
|
+
riskLevel: 'high'
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
pattern: 'constructor',
|
|
33
|
+
dangerous: true,
|
|
34
|
+
vulnerability: 'method-injection',
|
|
35
|
+
safeAlternative: 'Validate property names against whitelist',
|
|
36
|
+
example: {
|
|
37
|
+
bad: 'obj[userInput] = value; // if userInput is "constructor"',
|
|
38
|
+
good: 'const ALLOWED_KEYS = [\'name\', \'age\', \'email\']; if (ALLOWED_KEYS.includes(userInput)) obj[userInput] = value;'
|
|
39
|
+
},
|
|
40
|
+
effort: '10-15 minutes',
|
|
41
|
+
riskLevel: 'medium'
|
|
42
|
+
}
|
|
43
|
+
];
|
|
44
|
+
exports.detectObjectInjection = (0, eslint_devkit_2.createRule)({
|
|
45
|
+
name: 'detect-object-injection',
|
|
46
|
+
meta: {
|
|
47
|
+
type: 'problem',
|
|
48
|
+
docs: {
|
|
49
|
+
description: 'Detects variable[key] as a left- or right-hand assignment operand',
|
|
50
|
+
},
|
|
51
|
+
messages: {
|
|
52
|
+
// 🎯 Token optimization: 37% reduction (54→34 tokens) - removes verbose current/fix/doc labels
|
|
53
|
+
objectInjection: (0, eslint_devkit_1.formatLLMMessage)({
|
|
54
|
+
icon: eslint_devkit_1.MessageIcons.WARNING,
|
|
55
|
+
issueName: 'Object injection',
|
|
56
|
+
cwe: 'CWE-915',
|
|
57
|
+
description: 'Object injection/Prototype pollution (incl. model/tool outputs)',
|
|
58
|
+
severity: '{{riskLevel}}',
|
|
59
|
+
fix: '{{safeAlternative}}',
|
|
60
|
+
documentationLink: 'https://portswigger.net/web-security/prototype-pollution',
|
|
61
|
+
}),
|
|
62
|
+
useMapInstead: (0, eslint_devkit_1.formatLLMMessage)({
|
|
63
|
+
icon: eslint_devkit_1.MessageIcons.INFO,
|
|
64
|
+
issueName: 'Use Map',
|
|
65
|
+
description: 'Use Map instead of plain objects',
|
|
66
|
+
severity: 'LOW',
|
|
67
|
+
fix: 'const map = new Map(); map.set(key, value);',
|
|
68
|
+
documentationLink: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map',
|
|
69
|
+
}),
|
|
70
|
+
useHasOwnProperty: (0, eslint_devkit_1.formatLLMMessage)({
|
|
71
|
+
icon: eslint_devkit_1.MessageIcons.INFO,
|
|
72
|
+
issueName: 'Use hasOwnProperty',
|
|
73
|
+
description: 'Check hasOwnProperty to avoid prototype properties',
|
|
74
|
+
severity: 'LOW',
|
|
75
|
+
fix: 'if (obj.hasOwnProperty(key)) { obj[key] = value; }',
|
|
76
|
+
documentationLink: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty',
|
|
77
|
+
}),
|
|
78
|
+
whitelistKeys: (0, eslint_devkit_1.formatLLMMessage)({
|
|
79
|
+
icon: eslint_devkit_1.MessageIcons.INFO,
|
|
80
|
+
issueName: 'Whitelist Keys',
|
|
81
|
+
description: 'Whitelist allowed property names',
|
|
82
|
+
severity: 'LOW',
|
|
83
|
+
fix: 'const ALLOWED = ["name", "email"]; if (ALLOWED.includes(key)) obj[key] = value; // reject model/tool-supplied unknown keys',
|
|
84
|
+
documentationLink: 'https://portswigger.net/web-security/prototype-pollution',
|
|
85
|
+
}),
|
|
86
|
+
useObjectCreate: (0, eslint_devkit_1.formatLLMMessage)({
|
|
87
|
+
icon: eslint_devkit_1.MessageIcons.INFO,
|
|
88
|
+
issueName: 'Use Object.create(null)',
|
|
89
|
+
description: 'Create clean objects without prototypes',
|
|
90
|
+
severity: 'LOW',
|
|
91
|
+
fix: 'const obj = Object.create(null);',
|
|
92
|
+
documentationLink: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create',
|
|
93
|
+
}),
|
|
94
|
+
freezePrototypes: (0, eslint_devkit_1.formatLLMMessage)({
|
|
95
|
+
icon: eslint_devkit_1.MessageIcons.INFO,
|
|
96
|
+
issueName: 'Freeze Prototypes',
|
|
97
|
+
description: 'Freeze Object.prototype to prevent pollution',
|
|
98
|
+
severity: 'LOW',
|
|
99
|
+
fix: 'Object.freeze(Object.prototype);',
|
|
100
|
+
documentationLink: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze',
|
|
101
|
+
}),
|
|
102
|
+
strategyValidate: (0, eslint_devkit_1.formatLLMMessage)({
|
|
103
|
+
icon: eslint_devkit_1.MessageIcons.STRATEGY,
|
|
104
|
+
issueName: 'Validate Input',
|
|
105
|
+
description: 'Add input validation before property access',
|
|
106
|
+
severity: 'LOW',
|
|
107
|
+
fix: 'Validate key against allowed values before access',
|
|
108
|
+
documentationLink: 'https://portswigger.net/web-security/prototype-pollution',
|
|
109
|
+
}),
|
|
110
|
+
strategyWhitelist: (0, eslint_devkit_1.formatLLMMessage)({
|
|
111
|
+
icon: eslint_devkit_1.MessageIcons.STRATEGY,
|
|
112
|
+
issueName: 'Whitelist Properties',
|
|
113
|
+
description: 'Whitelist allowed property names only',
|
|
114
|
+
severity: 'LOW',
|
|
115
|
+
fix: 'Define allowed keys and validate against them',
|
|
116
|
+
documentationLink: 'https://portswigger.net/web-security/prototype-pollution',
|
|
117
|
+
}),
|
|
118
|
+
strategyFreeze: (0, eslint_devkit_1.formatLLMMessage)({
|
|
119
|
+
icon: eslint_devkit_1.MessageIcons.STRATEGY,
|
|
120
|
+
issueName: 'Freeze Prototypes',
|
|
121
|
+
description: 'Freeze prototypes to prevent pollution',
|
|
122
|
+
severity: 'LOW',
|
|
123
|
+
fix: 'Object.freeze(Object.prototype) at app startup',
|
|
124
|
+
documentationLink: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze',
|
|
125
|
+
})
|
|
126
|
+
},
|
|
127
|
+
schema: [
|
|
128
|
+
{
|
|
129
|
+
type: 'object',
|
|
130
|
+
properties: {
|
|
131
|
+
allowLiterals: {
|
|
132
|
+
type: 'boolean',
|
|
133
|
+
default: false,
|
|
134
|
+
description: 'Allow bracket notation with literal strings'
|
|
135
|
+
},
|
|
136
|
+
additionalMethods: {
|
|
137
|
+
type: 'array',
|
|
138
|
+
items: { type: 'string' },
|
|
139
|
+
default: [],
|
|
140
|
+
description: 'Additional object methods to check for injection'
|
|
141
|
+
},
|
|
142
|
+
dangerousProperties: {
|
|
143
|
+
type: 'array',
|
|
144
|
+
items: { type: 'string' },
|
|
145
|
+
default: ['__proto__', 'prototype', 'constructor'],
|
|
146
|
+
description: 'Properties to consider dangerous'
|
|
147
|
+
},
|
|
148
|
+
strategy: {
|
|
149
|
+
type: 'string',
|
|
150
|
+
enum: ['validate', 'whitelist', 'freeze', 'auto'],
|
|
151
|
+
default: 'auto',
|
|
152
|
+
description: 'Strategy for fixing object injection (auto = smart detection)'
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
additionalProperties: false,
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
},
|
|
159
|
+
defaultOptions: [
|
|
160
|
+
{
|
|
161
|
+
allowLiterals: false,
|
|
162
|
+
additionalMethods: [],
|
|
163
|
+
dangerousProperties: ['__proto__', 'prototype', 'constructor'],
|
|
164
|
+
strategy: 'auto'
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
create(context) {
|
|
168
|
+
const options = context.options[0] || {};
|
|
169
|
+
const { allowLiterals = false, dangerousProperties = ['__proto__', 'prototype', 'constructor'], } = options || {};
|
|
170
|
+
// Track MemberExpressions that are part of AssignmentExpressions to avoid double-reporting
|
|
171
|
+
const handledMemberExpressions = new WeakSet();
|
|
172
|
+
// Check if TypeScript parser services are available for type-aware checking
|
|
173
|
+
const hasTypeInfo = (0, eslint_devkit_1.hasParserServices)(context);
|
|
174
|
+
const parserServices = hasTypeInfo ? (0, eslint_devkit_1.getParserServices)(context) : null;
|
|
175
|
+
/**
|
|
176
|
+
* Check if a node is a literal string (potentially safe)
|
|
177
|
+
*/
|
|
178
|
+
const isLiteralString = (node) => {
|
|
179
|
+
return node.type === 'Literal' && typeof node.value === 'string';
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* Check if a property is part of a typed union (safe access)
|
|
183
|
+
*
|
|
184
|
+
* Type-Aware Enhancement:
|
|
185
|
+
* When TypeScript parser services are available, we can check if a variable
|
|
186
|
+
* is typed as a union of string literals (e.g., 'name' | 'email').
|
|
187
|
+
* Such accesses are safe because the values are statically constrained.
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* // This is now detected as SAFE (no false positive):
|
|
191
|
+
* const key: 'name' | 'email' = getKey();
|
|
192
|
+
* obj[key] = value;
|
|
193
|
+
*
|
|
194
|
+
* // This is still detected as DANGEROUS:
|
|
195
|
+
* const key: string = getUserInput();
|
|
196
|
+
* obj[key] = value;
|
|
197
|
+
*/
|
|
198
|
+
const isTypedUnionAccess = (propertyNode) => {
|
|
199
|
+
// Check if property is a literal string (typed access like obj['name'])
|
|
200
|
+
if (isLiteralString(propertyNode)) {
|
|
201
|
+
return true; // Literal strings are safe - they're typed at compile time
|
|
202
|
+
}
|
|
203
|
+
// Type-aware check: If we have TypeScript type information, check if the
|
|
204
|
+
// property key is constrained to a union of safe string literals
|
|
205
|
+
if (parserServices && propertyNode.type === 'Identifier') {
|
|
206
|
+
try {
|
|
207
|
+
const type = (0, eslint_devkit_1.getTypeOfNode)(propertyNode, parserServices);
|
|
208
|
+
// Check if the type is a union of safe string literals
|
|
209
|
+
// (excludes '__proto__', 'prototype', 'constructor')
|
|
210
|
+
if ((0, eslint_devkit_1.isUnionOfSafeStringLiterals)(type, dangerousProperties)) {
|
|
211
|
+
return true; // Safe - statically constrained to safe values
|
|
212
|
+
}
|
|
213
|
+
// Also check for single string literal type (e.g., const key: 'name' = ...)
|
|
214
|
+
const literalValues = (0, eslint_devkit_1.getStringLiteralValues)(type);
|
|
215
|
+
if (literalValues && literalValues.length === 1) {
|
|
216
|
+
// Single literal - safe if not dangerous
|
|
217
|
+
if (!dangerousProperties.includes(literalValues[0])) {
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
// If type checking fails, fall back to treating as potentially dangerous
|
|
224
|
+
// This can happen with malformed AST or missing type information
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// Without type information, treat all identifiers as potentially dangerous
|
|
228
|
+
return false;
|
|
229
|
+
};
|
|
230
|
+
/**
|
|
231
|
+
* Check if property access is potentially dangerous
|
|
232
|
+
*/
|
|
233
|
+
const isDangerousPropertyAccess = (propertyNode) => {
|
|
234
|
+
// Check if it's a literal string first
|
|
235
|
+
if (isLiteralString(propertyNode)) {
|
|
236
|
+
const propName = String(propertyNode.value);
|
|
237
|
+
// DANGEROUS: Literal strings that match dangerous properties (always flag these)
|
|
238
|
+
// Check this BEFORE checking typed union access
|
|
239
|
+
if (dangerousProperties.includes(propName)) {
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
// SAFE: Typed union access (obj[typedKey] where typedKey is 'primary' | 'secondary')
|
|
243
|
+
// Only safe if it's NOT a dangerous property
|
|
244
|
+
if (isTypedUnionAccess(propertyNode)) {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
// SAFE: Literal strings that are NOT dangerous properties (if allowLiterals is true)
|
|
248
|
+
if (allowLiterals) {
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
// If allowLiterals is false, non-dangerous literal strings are still considered safe
|
|
252
|
+
// (they're static and known at compile time)
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
// DANGEROUS: Any untyped/dynamic property access (e.g., obj[userInput])
|
|
256
|
+
return true;
|
|
257
|
+
};
|
|
258
|
+
/**
|
|
259
|
+
* Extract property access information
|
|
260
|
+
*/
|
|
261
|
+
const extractPropertyAccess = (node) => {
|
|
262
|
+
const sourceCode = context.sourceCode || context.sourceCode;
|
|
263
|
+
let object;
|
|
264
|
+
let property;
|
|
265
|
+
let propertyNode;
|
|
266
|
+
let isAssignment = false;
|
|
267
|
+
if (node.type === 'AssignmentExpression' && node.left.type === 'MemberExpression') {
|
|
268
|
+
// Assignment: obj[key] = value
|
|
269
|
+
object = sourceCode.getText(node.left.object);
|
|
270
|
+
property = sourceCode.getText(node.left.property);
|
|
271
|
+
propertyNode = node.left.property;
|
|
272
|
+
isAssignment = true;
|
|
273
|
+
}
|
|
274
|
+
else if (node.type === 'MemberExpression') {
|
|
275
|
+
// Access: obj[key]
|
|
276
|
+
object = sourceCode.getText(node.object);
|
|
277
|
+
property = sourceCode.getText(node.property);
|
|
278
|
+
propertyNode = node.property;
|
|
279
|
+
isAssignment = false;
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
return { object: '', property: '', propertyNode: node, isAssignment: false, pattern: null };
|
|
283
|
+
}
|
|
284
|
+
// Check if property matches dangerous patterns
|
|
285
|
+
const pattern = OBJECT_INJECTION_PATTERNS.find(p => new RegExp(p.pattern, 'i').test(property) ||
|
|
286
|
+
dangerousProperties.includes(property.replace(/['"]/g, ''))) || null;
|
|
287
|
+
return { object, property, propertyNode, isAssignment, pattern };
|
|
288
|
+
};
|
|
289
|
+
/**
|
|
290
|
+
* Determine if this is a high-risk assignment
|
|
291
|
+
*/
|
|
292
|
+
const isHighRiskAssignment = (node) => {
|
|
293
|
+
if (node.left.type !== 'MemberExpression') {
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
// Only check computed member access (bracket notation)
|
|
297
|
+
// Dot notation (obj.name) is safe
|
|
298
|
+
if (!node.left.computed) {
|
|
299
|
+
return false;
|
|
300
|
+
}
|
|
301
|
+
const { propertyNode } = extractPropertyAccess(node);
|
|
302
|
+
// Check for dangerous property access in assignment
|
|
303
|
+
return isDangerousPropertyAccess(propertyNode);
|
|
304
|
+
};
|
|
305
|
+
/**
|
|
306
|
+
* Determine if this is a high-risk member access
|
|
307
|
+
*/
|
|
308
|
+
const isHighRiskMemberAccess = (node) => {
|
|
309
|
+
// Only check computed member access (bracket notation)
|
|
310
|
+
if (!node.computed) {
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
const { propertyNode } = extractPropertyAccess(node);
|
|
314
|
+
// Check for dangerous property access
|
|
315
|
+
return isDangerousPropertyAccess(propertyNode);
|
|
316
|
+
};
|
|
317
|
+
/**
|
|
318
|
+
* Determine risk level based on the pattern and context
|
|
319
|
+
*/
|
|
320
|
+
const determineRiskLevel = (pattern, isAssignment) => {
|
|
321
|
+
if (pattern?.riskLevel === 'critical' || (pattern && isAssignment)) {
|
|
322
|
+
return 'CRITICAL';
|
|
323
|
+
}
|
|
324
|
+
if (pattern?.riskLevel === 'high' || isAssignment) {
|
|
325
|
+
return 'HIGH';
|
|
326
|
+
}
|
|
327
|
+
return 'MEDIUM';
|
|
328
|
+
};
|
|
329
|
+
/**
|
|
330
|
+
* Check assignment expressions for object injection
|
|
331
|
+
*/
|
|
332
|
+
const checkAssignmentExpression = (node) => {
|
|
333
|
+
if (!isHighRiskAssignment(node)) {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
// Mark the MemberExpression as handled to avoid double-reporting
|
|
337
|
+
if (node.left.type === 'MemberExpression') {
|
|
338
|
+
handledMemberExpressions.add(node.left);
|
|
339
|
+
}
|
|
340
|
+
const { object, property, isAssignment, pattern } = extractPropertyAccess(node);
|
|
341
|
+
const riskLevel = determineRiskLevel(pattern, isAssignment);
|
|
342
|
+
context.report({
|
|
343
|
+
node,
|
|
344
|
+
messageId: 'objectInjection',
|
|
345
|
+
data: {
|
|
346
|
+
pattern: `${object}[${property}]`,
|
|
347
|
+
riskLevel,
|
|
348
|
+
vulnerability: pattern?.vulnerability || 'object injection',
|
|
349
|
+
safeAlternative: pattern?.safeAlternative || 'Use Map or property whitelisting',
|
|
350
|
+
},
|
|
351
|
+
suggest: [
|
|
352
|
+
{
|
|
353
|
+
messageId: 'useMapInstead',
|
|
354
|
+
fix: () => null
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
messageId: 'useHasOwnProperty',
|
|
358
|
+
fix: () => null
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
messageId: 'whitelistKeys',
|
|
362
|
+
fix: () => null
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
messageId: 'useObjectCreate',
|
|
366
|
+
fix: () => null
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
messageId: 'freezePrototypes',
|
|
370
|
+
fix: () => null
|
|
371
|
+
}
|
|
372
|
+
]
|
|
373
|
+
});
|
|
374
|
+
};
|
|
375
|
+
/**
|
|
376
|
+
* Check member expressions for object injection
|
|
377
|
+
*/
|
|
378
|
+
const checkMemberExpression = (node) => {
|
|
379
|
+
if (!isHighRiskMemberAccess(node)) {
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
// Skip if this MemberExpression was already handled as part of an AssignmentExpression
|
|
383
|
+
if (handledMemberExpressions.has(node)) {
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
// Also check parent - if it's an AssignmentExpression and this node is the left side, skip
|
|
387
|
+
// (This handles cases where WeakSet check didn't work due to visitor order)
|
|
388
|
+
const parent = node.parent;
|
|
389
|
+
if (parent && parent.type === 'AssignmentExpression' && parent.left === node) {
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
const { object, property, isAssignment, pattern } = extractPropertyAccess(node);
|
|
393
|
+
const riskLevel = determineRiskLevel(pattern, isAssignment);
|
|
394
|
+
context.report({
|
|
395
|
+
node,
|
|
396
|
+
messageId: 'objectInjection',
|
|
397
|
+
data: {
|
|
398
|
+
pattern: `${object}[${property}]`,
|
|
399
|
+
riskLevel,
|
|
400
|
+
vulnerability: pattern?.vulnerability || 'object injection',
|
|
401
|
+
safeAlternative: pattern?.safeAlternative || 'Use Map or property whitelisting',
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
};
|
|
405
|
+
return {
|
|
406
|
+
AssignmentExpression: checkAssignmentExpression,
|
|
407
|
+
MemberExpression: checkMemberExpression
|
|
408
|
+
};
|
|
409
|
+
},
|
|
410
|
+
});
|
|
411
|
+
//# sourceMappingURL=detect-object-injection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-object-injection.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-secure-coding/src/rules/security/detect-object-injection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type SecurityRuleOptions } from '@interlace/eslint-devkit';
|
|
2
|
+
export interface Options extends SecurityRuleOptions {
|
|
3
|
+
/** Buffer methods to check for bounds safety */
|
|
4
|
+
bufferMethods?: string[];
|
|
5
|
+
/** Functions that validate buffer indices */
|
|
6
|
+
boundsCheckFunctions?: string[];
|
|
7
|
+
/** Buffer types to monitor */
|
|
8
|
+
bufferTypes?: string[];
|
|
9
|
+
/** Additional function names to consider as buffer index validators */
|
|
10
|
+
trustedSanitizers?: string[];
|
|
11
|
+
/** Additional JSDoc annotations to consider as safe markers */
|
|
12
|
+
strictMode?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare const noBufferOverread: ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
|