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,418 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.noUnvalidatedUserInput = void 0;
4
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
5
+ const eslint_devkit_2 = require("@interlace/eslint-devkit");
6
+ /**
7
+ * Patterns that indicate unvalidated user input
8
+ */
9
+ const UNVALIDATED_INPUT_PATTERNS = [
10
+ // Express/Node.js patterns
11
+ { pattern: /\breq\.body\b/, name: 'req.body', context: 'Express request body' },
12
+ { pattern: /\breq\.query\b/, name: 'req.query', context: 'Express query parameters' },
13
+ { pattern: /\breq\.params\b/, name: 'req.params', context: 'Express route parameters' },
14
+ { pattern: /\breq\.headers\b/, name: 'req.headers', context: 'Express headers' },
15
+ { pattern: /\breq\.cookies\b/, name: 'req.cookies', context: 'Express cookies' },
16
+ // Fastify patterns
17
+ { pattern: /\brequest\.body\b/, name: 'request.body', context: 'Fastify request body' },
18
+ { pattern: /\brequest\.query\b/, name: 'request.query', context: 'Fastify query parameters' },
19
+ { pattern: /\brequest\.params\b/, name: 'request.params', context: 'Fastify route parameters' },
20
+ // Next.js patterns
21
+ { pattern: /\bsearchParams\b/, name: 'searchParams', context: 'Next.js search params' },
22
+ // Generic patterns
23
+ { pattern: /\buserInput\b/, name: 'userInput', context: 'Generic user input' },
24
+ { pattern: /\binput\b/, name: 'input', context: 'Generic input variable' },
25
+ ];
26
+ /**
27
+ * Check if a node is inside a validation function call
28
+ */
29
+ function isInsideValidationCall(node, sourceCode, trustedLibraries) {
30
+ let current = node;
31
+ while (current) {
32
+ // Check if current is an argument to a CallExpression
33
+ if (current.parent && current.parent.type === 'CallExpression') {
34
+ const callExpr = current.parent;
35
+ // Verify that current is actually an argument of this call
36
+ const isArgument = callExpr.arguments.some((arg) => arg === current);
37
+ if (!isArgument) {
38
+ // Not an argument, continue traversing
39
+ if ('parent' in current && current.parent) {
40
+ current = current.parent;
41
+ continue;
42
+ }
43
+ else {
44
+ break;
45
+ }
46
+ }
47
+ const callee = callExpr.callee;
48
+ // Check if it's a validation library call (e.g., schema.parse(), schema.validate())
49
+ if (callee.type === 'MemberExpression') {
50
+ const property = callee.property;
51
+ if (property.type === 'Identifier') {
52
+ const methodName = property.name.toLowerCase();
53
+ // Check for validation methods (including async variants)
54
+ // Note: safeParse is one word, not two
55
+ if (['parse', 'validate', 'safeparse', 'parseasync', 'validateasync', 'safe_parse'].includes(methodName)) {
56
+ return true;
57
+ }
58
+ }
59
+ // Check if the object is a validation library
60
+ const object = callee.object;
61
+ if (object.type === 'Identifier') {
62
+ const objectName = object.name.toLowerCase();
63
+ if (trustedLibraries.some(lib => objectName.includes(lib.toLowerCase()))) {
64
+ return true;
65
+ }
66
+ }
67
+ }
68
+ // Check if it's a direct validation function call (e.g., validate(), plainToClass())
69
+ if (callee.type === 'Identifier') {
70
+ const calleeName = callee.name.toLowerCase();
71
+ if (['validate', 'plaintoclass', 'transform'].includes(calleeName)) {
72
+ return true;
73
+ }
74
+ if (trustedLibraries.some(lib => calleeName.includes(lib.toLowerCase()))) {
75
+ return true;
76
+ }
77
+ }
78
+ }
79
+ // Traverse up the AST
80
+ if ('parent' in current && current.parent) {
81
+ current = current.parent;
82
+ }
83
+ else {
84
+ break;
85
+ }
86
+ }
87
+ return false;
88
+ }
89
+ /**
90
+ * Check if a string matches any ignore pattern
91
+ */
92
+ function matchesIgnorePattern(text, ignorePatterns) {
93
+ return ignorePatterns.some(pattern => {
94
+ try {
95
+ const regex = new RegExp(pattern, 'i');
96
+ return regex.test(text);
97
+ }
98
+ catch {
99
+ // Invalid regex - treat as literal string match
100
+ return text.toLowerCase().includes(pattern.toLowerCase());
101
+ }
102
+ });
103
+ }
104
+ exports.noUnvalidatedUserInput = (0, eslint_devkit_2.createRule)({
105
+ name: 'no-unvalidated-user-input',
106
+ meta: {
107
+ type: 'problem',
108
+ docs: {
109
+ description: 'Detects unvalidated user input usage (req.body, req.query, etc.)',
110
+ },
111
+ hasSuggestions: true,
112
+ messages: {
113
+ unvalidatedInput: (0, eslint_devkit_1.formatLLMMessage)({
114
+ icon: eslint_devkit_1.MessageIcons.SECURITY,
115
+ issueName: 'Unvalidated User Input',
116
+ cwe: 'CWE-20',
117
+ description: 'Unvalidated user input detected: {{inputSource}}',
118
+ severity: 'HIGH',
119
+ fix: 'Use validation library: {{validationExample}}',
120
+ documentationLink: 'https://cwe.mitre.org/data/definitions/20.html',
121
+ }),
122
+ useValidationLibrary: (0, eslint_devkit_1.formatLLMMessage)({
123
+ icon: eslint_devkit_1.MessageIcons.INFO,
124
+ issueName: 'Use Validation Library',
125
+ description: 'Use validation library',
126
+ severity: 'LOW',
127
+ fix: 'Use Zod, Joi, Yup, or class-validator',
128
+ documentationLink: 'https://zod.dev/',
129
+ }),
130
+ useZod: (0, eslint_devkit_1.formatLLMMessage)({
131
+ icon: eslint_devkit_1.MessageIcons.INFO,
132
+ issueName: 'Use Zod',
133
+ description: 'Use Zod for validation',
134
+ severity: 'LOW',
135
+ fix: 'const data = z.object({ name: z.string() }).parse(req.body)',
136
+ documentationLink: 'https://zod.dev/',
137
+ }),
138
+ useJoi: (0, eslint_devkit_1.formatLLMMessage)({
139
+ icon: eslint_devkit_1.MessageIcons.INFO,
140
+ issueName: 'Use Joi',
141
+ description: 'Use Joi for validation',
142
+ severity: 'LOW',
143
+ fix: 'Joi.object({ name: Joi.string() }).validate(req.body)',
144
+ documentationLink: 'https://joi.dev/',
145
+ }),
146
+ },
147
+ schema: [
148
+ {
149
+ type: 'object',
150
+ properties: {
151
+ allowInTests: {
152
+ type: 'boolean',
153
+ default: false,
154
+ description: 'Allow unvalidated input in test files',
155
+ },
156
+ trustedLibraries: {
157
+ type: 'array',
158
+ items: { type: 'string' },
159
+ default: ['zod', 'joi', 'yup', 'class-validator'],
160
+ description: 'Trusted validation libraries',
161
+ },
162
+ ignorePatterns: {
163
+ type: 'array',
164
+ items: { type: 'string' },
165
+ default: [],
166
+ description: 'Additional safe patterns to ignore',
167
+ },
168
+ },
169
+ additionalProperties: false,
170
+ },
171
+ ],
172
+ },
173
+ defaultOptions: [
174
+ {
175
+ allowInTests: false,
176
+ trustedLibraries: ['zod', 'joi', 'yup', 'class-validator'],
177
+ ignorePatterns: [],
178
+ },
179
+ ],
180
+ create(context, [options = {}]) {
181
+ const { allowInTests = false, trustedLibraries = ['zod', 'joi', 'yup', 'class-validator'], ignorePatterns = [], } = options;
182
+ const filename = context.getFilename();
183
+ const isTestFile = allowInTests && /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(filename);
184
+ const sourceCode = context.sourceCode || context.sourceCode;
185
+ function checkMemberExpression(node) {
186
+ if (isTestFile) {
187
+ return;
188
+ }
189
+ const text = sourceCode.getText(node);
190
+ // Check if the variable name (if in assignment) matches ignore pattern
191
+ // For cases like: const safeInput = req.body;
192
+ if (node.parent && node.parent.type === 'VariableDeclarator' && node.parent.id.type === 'Identifier') {
193
+ const varName = node.parent.id.name;
194
+ if (matchesIgnorePattern(varName, ignorePatterns)) {
195
+ return;
196
+ }
197
+ }
198
+ // Check if it matches any ignore pattern
199
+ if (matchesIgnorePattern(text, ignorePatterns)) {
200
+ return;
201
+ }
202
+ // Check if it matches unvalidated input patterns
203
+ // For nested member expressions like req.body.name, check the base (req.body)
204
+ let baseText = text;
205
+ if (node.object.type === 'MemberExpression') {
206
+ baseText = sourceCode.getText(node.object);
207
+ }
208
+ const matchedPattern = UNVALIDATED_INPUT_PATTERNS.find(p => p.pattern.test(text) || p.pattern.test(baseText));
209
+ if (matchedPattern) {
210
+ // Skip if this is a nested member expression and the parent also matches
211
+ // This prevents double reporting for cases like req.query.id
212
+ // We only want to report on the outermost matching expression
213
+ if (node.object.type === 'MemberExpression') {
214
+ const parentText = sourceCode.getText(node.object);
215
+ const parentMatches = UNVALIDATED_INPUT_PATTERNS.some(p => p.pattern.test(parentText));
216
+ if (parentMatches) {
217
+ // Parent also matches, skip this nested one - it will be reported when we visit the parent
218
+ return;
219
+ }
220
+ }
221
+ // Skip if this is in a destructuring assignment - checkObjectPattern will handle it
222
+ // This prevents double reporting for cases like: const { email } = req.body;
223
+ if (node.parent && node.parent.type === 'VariableDeclarator' && node.parent.id.type === 'ObjectPattern') {
224
+ return; // checkObjectPattern will report on the init instead
225
+ }
226
+ // Check if it's inside a validation call
227
+ if (isInsideValidationCall(node, sourceCode, trustedLibraries)) {
228
+ return;
229
+ }
230
+ // Determine validation example based on context
231
+ let validationExample = 'const schema = z.object({ field: z.string() }); const data = schema.parse(req.body);';
232
+ if (text.includes('query')) {
233
+ validationExample = 'const schema = z.object({ id: z.string() }); const data = schema.parse(req.query);';
234
+ }
235
+ else if (text.includes('params')) {
236
+ validationExample = 'const schema = z.object({ id: z.string() }); const data = schema.parse(req.params);';
237
+ }
238
+ // Build suggestions - provide same code as output for test framework recognition
239
+ const suggestions = [
240
+ {
241
+ messageId: 'useZod',
242
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
243
+ fix: (_fixer) => {
244
+ // This is a suggestion, not an auto-fix, so we return null
245
+ return null;
246
+ },
247
+ },
248
+ {
249
+ messageId: 'useJoi',
250
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
251
+ fix: (_fixer) => {
252
+ return null;
253
+ },
254
+ },
255
+ ];
256
+ context.report({
257
+ node,
258
+ messageId: 'unvalidatedInput',
259
+ data: {
260
+ inputSource: matchedPattern.name,
261
+ validationExample,
262
+ },
263
+ suggest: suggestions,
264
+ });
265
+ }
266
+ }
267
+ function checkIdentifier(node) {
268
+ if (isTestFile) {
269
+ return;
270
+ }
271
+ const text = node.name;
272
+ // Check if it matches any ignore pattern
273
+ if (matchesIgnorePattern(text, ignorePatterns)) {
274
+ return;
275
+ }
276
+ // Skip if this identifier is assigned from a user input source (MemberExpression)
277
+ // For cases like: const userInput = req.body;
278
+ // We should only report on req.body, not on userInput
279
+ // But don't skip if the init is the same identifier (e.g., const data = input;)
280
+ if (node.parent && node.parent.type === 'VariableDeclarator' && node.parent.init) {
281
+ const init = node.parent.init;
282
+ // Only skip if init is a MemberExpression (like req.body) that will be caught by checkMemberExpression
283
+ // Don't skip if init is the same identifier (like input) - we want to report on it
284
+ if (init.type === 'MemberExpression') {
285
+ const initText = sourceCode.getText(init);
286
+ // Check if init matches any user input pattern
287
+ const initMatchesPattern = UNVALIDATED_INPUT_PATTERNS.some(p => p.pattern.test(initText));
288
+ if (initMatchesPattern) {
289
+ return; // Skip - the init (e.g., req.body) will be reported by checkMemberExpression
290
+ }
291
+ }
292
+ }
293
+ // Check for generic input patterns (userInput, input)
294
+ const matchedPattern = UNVALIDATED_INPUT_PATTERNS.find(p => (p.name === 'userInput' || p.name === 'input') && p.pattern.test(text));
295
+ if (matchedPattern) {
296
+ // Check if it's inside a validation call
297
+ if (isInsideValidationCall(node, sourceCode, trustedLibraries)) {
298
+ return;
299
+ }
300
+ context.report({
301
+ node,
302
+ messageId: 'unvalidatedInput',
303
+ data: {
304
+ inputSource: matchedPattern.name,
305
+ validationExample: 'const schema = z.object({ field: z.string() }); const data = schema.parse(input);',
306
+ },
307
+ suggest: [
308
+ {
309
+ messageId: 'useZod',
310
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
311
+ fix: (_fixer) => null,
312
+ },
313
+ {
314
+ messageId: 'useJoi',
315
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
316
+ fix: (_fixer) => null,
317
+ },
318
+ ],
319
+ });
320
+ }
321
+ }
322
+ function checkObjectPattern(node) {
323
+ if (isTestFile) {
324
+ return;
325
+ }
326
+ // Check destructuring patterns like: const { page, limit } = req.query;
327
+ if (node.parent && node.parent.type === 'VariableDeclarator' && node.parent.init) {
328
+ const init = node.parent.init;
329
+ const initText = sourceCode.getText(init);
330
+ // If init is a CallExpression, check if it's a validation call
331
+ // If so, the input is being validated, so skip
332
+ if (init.type === 'CallExpression') {
333
+ const callee = init.callee;
334
+ if (callee.type === 'MemberExpression' && callee.property.type === 'Identifier') {
335
+ const methodName = callee.property.name.toLowerCase();
336
+ if (['parse', 'validate', 'safeparse', 'parseasync', 'validateasync', 'safe_parse'].includes(methodName)) {
337
+ return; // It's a validation call, skip
338
+ }
339
+ }
340
+ if (callee.type === 'Identifier') {
341
+ const calleeName = callee.name.toLowerCase();
342
+ if (['validate', 'plaintoclass', 'transform'].includes(calleeName)) {
343
+ return; // It's a validation call, skip
344
+ }
345
+ }
346
+ }
347
+ // Check if the right side matches unvalidated input patterns
348
+ const matchedPattern = UNVALIDATED_INPUT_PATTERNS.find(p => p.pattern.test(initText));
349
+ if (matchedPattern) {
350
+ // For CallExpressions, check the arguments to see if they're validated
351
+ // The init itself being a validation call was already checked above
352
+ if (init.type === 'CallExpression') {
353
+ // Check each argument to see if it's validated
354
+ // If init is a validation call (like schema.validate(req.body)),
355
+ // then req.body is validated, so skip
356
+ const callee = init.callee;
357
+ const isValidationCall = (callee.type === 'MemberExpression' && callee.property.type === 'Identifier' &&
358
+ ['parse', 'validate', 'safeparse', 'parseasync', 'validateasync', 'safe_parse'].includes(callee.property.name.toLowerCase())) ||
359
+ (callee.type === 'Identifier' &&
360
+ ['validate', 'plaintoclass', 'transform'].includes(callee.name.toLowerCase()));
361
+ if (isValidationCall) {
362
+ return; // The init is a validation call, so the input is validated
363
+ }
364
+ // If init is not a validation call, check if arguments are validated
365
+ const hasValidatedArg = init.arguments.some((arg) => {
366
+ if (arg.type === 'MemberExpression' || arg.type === 'Identifier') {
367
+ return isInsideValidationCall(arg, sourceCode, trustedLibraries);
368
+ }
369
+ return false;
370
+ });
371
+ if (hasValidatedArg) {
372
+ return; // At least one argument is validated
373
+ }
374
+ }
375
+ else {
376
+ // For non-call expressions, check if init itself is inside a validation call
377
+ if (isInsideValidationCall(init, sourceCode, trustedLibraries)) {
378
+ return;
379
+ }
380
+ }
381
+ // Check if variable name matches ignore pattern
382
+ if (node.parent.id.type === 'ObjectPattern') {
383
+ const varText = sourceCode.getText(node.parent.id);
384
+ if (matchesIgnorePattern(varText, ignorePatterns)) {
385
+ return;
386
+ }
387
+ }
388
+ context.report({
389
+ node: init,
390
+ messageId: 'unvalidatedInput',
391
+ data: {
392
+ inputSource: matchedPattern.name,
393
+ validationExample: 'const schema = z.object({ page: z.string(), limit: z.string() }); const { page, limit } = schema.parse(req.query);',
394
+ },
395
+ suggest: [
396
+ {
397
+ messageId: 'useZod',
398
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
399
+ fix: (_fixer) => null,
400
+ },
401
+ {
402
+ messageId: 'useJoi',
403
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
404
+ fix: (_fixer) => null,
405
+ },
406
+ ],
407
+ });
408
+ }
409
+ }
410
+ }
411
+ return {
412
+ MemberExpression: checkMemberExpression,
413
+ Identifier: checkIdentifier,
414
+ ObjectPattern: checkObjectPattern,
415
+ };
416
+ },
417
+ });
418
+ //# sourceMappingURL=no-unvalidated-user-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-unvalidated-user-input.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-secure-coding/src/rules/security/no-unvalidated-user-input.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export interface Options {
2
+ /** Allow weak crypto in test files. Default: false */
3
+ allowInTests?: boolean;
4
+ /** Additional weak algorithms to detect. Default: [] */
5
+ additionalWeakAlgorithms?: string[];
6
+ /** Trusted crypto libraries. Default: ['crypto', 'crypto-js'] */
7
+ trustedLibraries?: string[];
8
+ /** Strategy for fixing weak crypto: 'upgrade', 'migrate', 'policy', 'auto' */
9
+ strategy?: 'upgrade' | 'migrate' | 'policy' | 'auto';
10
+ }
11
+ export declare const noWeakCrypto: ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;