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.
Files changed (155) hide show
  1. package/AGENTS.md +196 -0
  2. package/CHANGELOG.md +105 -0
  3. package/LICENSE +23 -0
  4. package/README.md +377 -0
  5. package/package.json +80 -0
  6. package/src/index.d.ts +32 -0
  7. package/src/index.js +345 -0
  8. package/src/index.js.map +1 -0
  9. package/src/rules/security/database-injection.d.ts +13 -0
  10. package/src/rules/security/database-injection.js +407 -0
  11. package/src/rules/security/database-injection.js.map +1 -0
  12. package/src/rules/security/detect-child-process.d.ts +11 -0
  13. package/src/rules/security/detect-child-process.js +460 -0
  14. package/src/rules/security/detect-child-process.js.map +1 -0
  15. package/src/rules/security/detect-eval-with-expression.d.ts +9 -0
  16. package/src/rules/security/detect-eval-with-expression.js +393 -0
  17. package/src/rules/security/detect-eval-with-expression.js.map +1 -0
  18. package/src/rules/security/detect-non-literal-fs-filename.d.ts +7 -0
  19. package/src/rules/security/detect-non-literal-fs-filename.js +322 -0
  20. package/src/rules/security/detect-non-literal-fs-filename.js.map +1 -0
  21. package/src/rules/security/detect-non-literal-regexp.d.ts +9 -0
  22. package/src/rules/security/detect-non-literal-regexp.js +387 -0
  23. package/src/rules/security/detect-non-literal-regexp.js.map +1 -0
  24. package/src/rules/security/detect-object-injection.d.ts +11 -0
  25. package/src/rules/security/detect-object-injection.js +411 -0
  26. package/src/rules/security/detect-object-injection.js.map +1 -0
  27. package/src/rules/security/no-buffer-overread.d.ts +14 -0
  28. package/src/rules/security/no-buffer-overread.js +519 -0
  29. package/src/rules/security/no-buffer-overread.js.map +1 -0
  30. package/src/rules/security/no-clickjacking.d.ts +10 -0
  31. package/src/rules/security/no-clickjacking.js +381 -0
  32. package/src/rules/security/no-clickjacking.js.map +1 -0
  33. package/src/rules/security/no-directive-injection.d.ts +12 -0
  34. package/src/rules/security/no-directive-injection.js +446 -0
  35. package/src/rules/security/no-directive-injection.js.map +1 -0
  36. package/src/rules/security/no-document-cookie.d.ts +5 -0
  37. package/src/rules/security/no-document-cookie.js +90 -0
  38. package/src/rules/security/no-document-cookie.js.map +1 -0
  39. package/src/rules/security/no-electron-security-issues.d.ts +10 -0
  40. package/src/rules/security/no-electron-security-issues.js +421 -0
  41. package/src/rules/security/no-electron-security-issues.js.map +1 -0
  42. package/src/rules/security/no-exposed-sensitive-data.d.ts +11 -0
  43. package/src/rules/security/no-exposed-sensitive-data.js +341 -0
  44. package/src/rules/security/no-exposed-sensitive-data.js.map +1 -0
  45. package/src/rules/security/no-format-string-injection.d.ts +17 -0
  46. package/src/rules/security/no-format-string-injection.js +653 -0
  47. package/src/rules/security/no-format-string-injection.js.map +1 -0
  48. package/src/rules/security/no-graphql-injection.d.ts +12 -0
  49. package/src/rules/security/no-graphql-injection.js +410 -0
  50. package/src/rules/security/no-graphql-injection.js.map +1 -0
  51. package/src/rules/security/no-hardcoded-credentials.d.ts +26 -0
  52. package/src/rules/security/no-hardcoded-credentials.js +377 -0
  53. package/src/rules/security/no-hardcoded-credentials.js.map +1 -0
  54. package/src/rules/security/no-improper-sanitization.d.ts +12 -0
  55. package/src/rules/security/no-improper-sanitization.js +408 -0
  56. package/src/rules/security/no-improper-sanitization.js.map +1 -0
  57. package/src/rules/security/no-improper-type-validation.d.ts +10 -0
  58. package/src/rules/security/no-improper-type-validation.js +420 -0
  59. package/src/rules/security/no-improper-type-validation.js.map +1 -0
  60. package/src/rules/security/no-insecure-comparison.d.ts +7 -0
  61. package/src/rules/security/no-insecure-comparison.js +125 -0
  62. package/src/rules/security/no-insecure-comparison.js.map +1 -0
  63. package/src/rules/security/no-insecure-cookie-settings.d.ts +9 -0
  64. package/src/rules/security/no-insecure-cookie-settings.js +305 -0
  65. package/src/rules/security/no-insecure-cookie-settings.js.map +1 -0
  66. package/src/rules/security/no-insecure-jwt.d.ts +10 -0
  67. package/src/rules/security/no-insecure-jwt.js +338 -0
  68. package/src/rules/security/no-insecure-jwt.js.map +1 -0
  69. package/src/rules/security/no-insecure-redirects.d.ts +7 -0
  70. package/src/rules/security/no-insecure-redirects.js +215 -0
  71. package/src/rules/security/no-insecure-redirects.js.map +1 -0
  72. package/src/rules/security/no-insufficient-postmessage-validation.d.ts +14 -0
  73. package/src/rules/security/no-insufficient-postmessage-validation.js +390 -0
  74. package/src/rules/security/no-insufficient-postmessage-validation.js.map +1 -0
  75. package/src/rules/security/no-insufficient-random.d.ts +9 -0
  76. package/src/rules/security/no-insufficient-random.js +207 -0
  77. package/src/rules/security/no-insufficient-random.js.map +1 -0
  78. package/src/rules/security/no-ldap-injection.d.ts +10 -0
  79. package/src/rules/security/no-ldap-injection.js +449 -0
  80. package/src/rules/security/no-ldap-injection.js.map +1 -0
  81. package/src/rules/security/no-missing-authentication.d.ts +13 -0
  82. package/src/rules/security/no-missing-authentication.js +322 -0
  83. package/src/rules/security/no-missing-authentication.js.map +1 -0
  84. package/src/rules/security/no-missing-cors-check.d.ts +9 -0
  85. package/src/rules/security/no-missing-cors-check.js +449 -0
  86. package/src/rules/security/no-missing-cors-check.js.map +1 -0
  87. package/src/rules/security/no-missing-csrf-protection.d.ts +11 -0
  88. package/src/rules/security/no-missing-csrf-protection.js +183 -0
  89. package/src/rules/security/no-missing-csrf-protection.js.map +1 -0
  90. package/src/rules/security/no-missing-security-headers.d.ts +7 -0
  91. package/src/rules/security/no-missing-security-headers.js +217 -0
  92. package/src/rules/security/no-missing-security-headers.js.map +1 -0
  93. package/src/rules/security/no-privilege-escalation.d.ts +13 -0
  94. package/src/rules/security/no-privilege-escalation.js +321 -0
  95. package/src/rules/security/no-privilege-escalation.js.map +1 -0
  96. package/src/rules/security/no-redos-vulnerable-regex.d.ts +7 -0
  97. package/src/rules/security/no-redos-vulnerable-regex.js +307 -0
  98. package/src/rules/security/no-redos-vulnerable-regex.js.map +1 -0
  99. package/src/rules/security/no-sensitive-data-exposure.d.ts +11 -0
  100. package/src/rules/security/no-sensitive-data-exposure.js +251 -0
  101. package/src/rules/security/no-sensitive-data-exposure.js.map +1 -0
  102. package/src/rules/security/no-sql-injection.d.ts +10 -0
  103. package/src/rules/security/no-sql-injection.js +332 -0
  104. package/src/rules/security/no-sql-injection.js.map +1 -0
  105. package/src/rules/security/no-timing-attack.d.ts +10 -0
  106. package/src/rules/security/no-timing-attack.js +358 -0
  107. package/src/rules/security/no-timing-attack.js.map +1 -0
  108. package/src/rules/security/no-toctou-vulnerability.d.ts +7 -0
  109. package/src/rules/security/no-toctou-vulnerability.js +165 -0
  110. package/src/rules/security/no-toctou-vulnerability.js.map +1 -0
  111. package/src/rules/security/no-unchecked-loop-condition.d.ts +12 -0
  112. package/src/rules/security/no-unchecked-loop-condition.js +635 -0
  113. package/src/rules/security/no-unchecked-loop-condition.js.map +1 -0
  114. package/src/rules/security/no-unencrypted-transmission.d.ts +11 -0
  115. package/src/rules/security/no-unencrypted-transmission.js +237 -0
  116. package/src/rules/security/no-unencrypted-transmission.js.map +1 -0
  117. package/src/rules/security/no-unescaped-url-parameter.d.ts +9 -0
  118. package/src/rules/security/no-unescaped-url-parameter.js +266 -0
  119. package/src/rules/security/no-unescaped-url-parameter.js.map +1 -0
  120. package/src/rules/security/no-unlimited-resource-allocation.d.ts +12 -0
  121. package/src/rules/security/no-unlimited-resource-allocation.js +659 -0
  122. package/src/rules/security/no-unlimited-resource-allocation.js.map +1 -0
  123. package/src/rules/security/no-unsafe-deserialization.d.ts +10 -0
  124. package/src/rules/security/no-unsafe-deserialization.js +501 -0
  125. package/src/rules/security/no-unsafe-deserialization.js.map +1 -0
  126. package/src/rules/security/no-unsafe-dynamic-require.d.ts +5 -0
  127. package/src/rules/security/no-unsafe-dynamic-require.js +107 -0
  128. package/src/rules/security/no-unsafe-dynamic-require.js.map +1 -0
  129. package/src/rules/security/no-unsafe-regex-construction.d.ts +9 -0
  130. package/src/rules/security/no-unsafe-regex-construction.js +292 -0
  131. package/src/rules/security/no-unsafe-regex-construction.js.map +1 -0
  132. package/src/rules/security/no-unsanitized-html.d.ts +9 -0
  133. package/src/rules/security/no-unsanitized-html.js +347 -0
  134. package/src/rules/security/no-unsanitized-html.js.map +1 -0
  135. package/src/rules/security/no-unvalidated-user-input.d.ts +9 -0
  136. package/src/rules/security/no-unvalidated-user-input.js +418 -0
  137. package/src/rules/security/no-unvalidated-user-input.js.map +1 -0
  138. package/src/rules/security/no-weak-crypto.d.ts +11 -0
  139. package/src/rules/security/no-weak-crypto.js +350 -0
  140. package/src/rules/security/no-weak-crypto.js.map +1 -0
  141. package/src/rules/security/no-weak-password-recovery.d.ts +12 -0
  142. package/src/rules/security/no-weak-password-recovery.js +401 -0
  143. package/src/rules/security/no-weak-password-recovery.js.map +1 -0
  144. package/src/rules/security/no-xpath-injection.d.ts +10 -0
  145. package/src/rules/security/no-xpath-injection.js +487 -0
  146. package/src/rules/security/no-xpath-injection.js.map +1 -0
  147. package/src/rules/security/no-xxe-injection.d.ts +7 -0
  148. package/src/rules/security/no-xxe-injection.js +270 -0
  149. package/src/rules/security/no-xxe-injection.js.map +1 -0
  150. package/src/rules/security/no-zip-slip.d.ts +9 -0
  151. package/src/rules/security/no-zip-slip.js +446 -0
  152. package/src/rules/security/no-zip-slip.js.map +1 -0
  153. package/src/types/index.d.ts +131 -0
  154. package/src/types/index.js +18 -0
  155. 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>;