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,350 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.noWeakCrypto = void 0;
4
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
5
+ const eslint_devkit_2 = require("@interlace/eslint-devkit");
6
+ const WEAK_CRYPTO_PATTERNS = [
7
+ {
8
+ pattern: /\bmd5\b/i,
9
+ name: 'MD5',
10
+ category: 'hash',
11
+ alternatives: ['SHA-256', 'SHA-512', 'SHA-3'],
12
+ example: {
13
+ bad: 'crypto.createHash("md5").update(data)',
14
+ good: 'crypto.createHash("sha256").update(data)'
15
+ },
16
+ effort: '5 minutes'
17
+ },
18
+ {
19
+ pattern: /\bsha1\b/i,
20
+ name: 'SHA-1',
21
+ category: 'hash',
22
+ alternatives: ['SHA-256', 'SHA-512', 'SHA-3'],
23
+ example: {
24
+ bad: 'crypto.createHash("sha1").update(data)',
25
+ good: 'crypto.createHash("sha256").update(data)'
26
+ },
27
+ effort: '5 minutes'
28
+ },
29
+ {
30
+ pattern: /\bdes\b/i,
31
+ name: 'DES',
32
+ category: 'encryption',
33
+ alternatives: ['AES-256', 'ChaCha20-Poly1305'],
34
+ example: {
35
+ bad: 'crypto.createCipher("des", key)',
36
+ good: 'crypto.createCipheriv("aes-256-gcm", key, iv)'
37
+ },
38
+ effort: '15 minutes'
39
+ },
40
+ {
41
+ pattern: /\b3des\b|\btripledes\b/i,
42
+ name: '3DES',
43
+ category: 'encryption',
44
+ alternatives: ['AES-256', 'ChaCha20-Poly1305'],
45
+ example: {
46
+ bad: 'crypto.createCipher("des-ede3", key)',
47
+ good: 'crypto.createCipheriv("aes-256-gcm", key, iv)'
48
+ },
49
+ effort: '15 minutes'
50
+ },
51
+ {
52
+ pattern: /\brc4\b/i,
53
+ name: 'RC4',
54
+ category: 'encryption',
55
+ alternatives: ['AES-256', 'ChaCha20-Poly1305'],
56
+ example: {
57
+ bad: 'crypto.createCipher("rc4", key)',
58
+ good: 'crypto.createCipheriv("aes-256-gcm", key, iv)'
59
+ },
60
+ effort: '15 minutes'
61
+ }
62
+ ];
63
+ /**
64
+ * Check if a string contains a weak crypto algorithm
65
+ */
66
+ function containsWeakCrypto(value, additionalPatterns) {
67
+ // Check standard patterns
68
+ for (const pattern of WEAK_CRYPTO_PATTERNS) {
69
+ if (pattern.pattern.test(value)) {
70
+ return pattern;
71
+ }
72
+ }
73
+ // Check additional patterns
74
+ for (const additionalPattern of additionalPatterns) {
75
+ const regex = new RegExp(`\\b${additionalPattern}\\b`, 'i');
76
+ if (regex.test(value)) {
77
+ return {
78
+ pattern: regex,
79
+ name: additionalPattern,
80
+ category: 'hash',
81
+ alternatives: ['SHA-256', 'SHA-512'],
82
+ example: {
83
+ bad: `crypto.createHash("${additionalPattern}").update(data)`,
84
+ good: 'crypto.createHash("sha256").update(data)'
85
+ },
86
+ effort: '10 minutes'
87
+ };
88
+ }
89
+ }
90
+ return null;
91
+ }
92
+ /**
93
+ * Generate refactoring suggestions based on the weak crypto pattern
94
+ */
95
+ function generateRefactoringSteps(pattern, context) {
96
+ const suggestions = [];
97
+ if (pattern.category === 'hash') {
98
+ suggestions.push({
99
+ messageId: 'useSha256',
100
+ fix: `Use SHA-256: crypto.createHash("sha256").update(${context})`
101
+ });
102
+ }
103
+ else if (pattern.category === 'encryption') {
104
+ suggestions.push({
105
+ messageId: 'useAes256',
106
+ fix: `Use AES-256-GCM: crypto.createCipheriv("aes-256-gcm", key, iv)`
107
+ });
108
+ }
109
+ if (pattern.category === 'password') {
110
+ suggestions.push({
111
+ messageId: 'useBcrypt',
112
+ fix: 'Use bcrypt: bcrypt.hash(password, 10)'
113
+ });
114
+ suggestions.push({
115
+ messageId: 'useScrypt',
116
+ fix: 'Use scrypt: crypto.scrypt(password, salt, 64)'
117
+ });
118
+ suggestions.push({
119
+ messageId: 'useArgon2',
120
+ fix: 'Use Argon2: argon2.hash(password)'
121
+ });
122
+ }
123
+ return suggestions;
124
+ }
125
+ exports.noWeakCrypto = (0, eslint_devkit_2.createRule)({
126
+ name: 'no-weak-crypto',
127
+ meta: {
128
+ type: 'problem',
129
+ docs: {
130
+ description: 'Detects use of weak cryptography algorithms (MD5, SHA1, DES)',
131
+ },
132
+ hasSuggestions: true,
133
+ messages: {
134
+ weakCrypto: (0, eslint_devkit_1.formatLLMMessage)({
135
+ icon: eslint_devkit_1.MessageIcons.SECURITY,
136
+ issueName: 'Weak cryptography',
137
+ cwe: 'CWE-327',
138
+ description: 'Use of weak cryptography algorithm: {{algorithm}}',
139
+ severity: 'CRITICAL',
140
+ fix: '{{safeAlternative}}',
141
+ documentationLink: 'https://owasp.org/www-community/vulnerabilities/Weak_Cryptography',
142
+ }),
143
+ useSha256: (0, eslint_devkit_1.formatLLMMessage)({
144
+ icon: eslint_devkit_1.MessageIcons.INFO,
145
+ issueName: 'Use SHA-256',
146
+ description: 'Use SHA-256 for hashing',
147
+ severity: 'LOW',
148
+ fix: 'crypto.createHash("sha256").update(data)',
149
+ documentationLink: 'https://nodejs.org/api/crypto.html#cryptocreatehashmethod-options',
150
+ }),
151
+ useBcrypt: (0, eslint_devkit_1.formatLLMMessage)({
152
+ icon: eslint_devkit_1.MessageIcons.INFO,
153
+ issueName: 'Use bcrypt',
154
+ description: 'Use bcrypt for password hashing',
155
+ severity: 'LOW',
156
+ fix: 'bcrypt.hash(password, 10)',
157
+ documentationLink: 'https://github.com/kelektiv/node.bcrypt.js',
158
+ }),
159
+ useScrypt: (0, eslint_devkit_1.formatLLMMessage)({
160
+ icon: eslint_devkit_1.MessageIcons.INFO,
161
+ issueName: 'Use scrypt',
162
+ description: 'Use scrypt for password hashing',
163
+ severity: 'LOW',
164
+ fix: 'crypto.scrypt(password, salt, 64)',
165
+ documentationLink: 'https://nodejs.org/api/crypto.html#cryptoscryptpassword-salt-keylen-options-callback',
166
+ }),
167
+ useArgon2: (0, eslint_devkit_1.formatLLMMessage)({
168
+ icon: eslint_devkit_1.MessageIcons.INFO,
169
+ issueName: 'Use Argon2',
170
+ description: 'Use Argon2 for password hashing',
171
+ severity: 'LOW',
172
+ fix: 'argon2.hash(password)',
173
+ documentationLink: 'https://github.com/ranisalt/node-argon2',
174
+ }),
175
+ useAes256: (0, eslint_devkit_1.formatLLMMessage)({
176
+ icon: eslint_devkit_1.MessageIcons.INFO,
177
+ issueName: 'Use AES-256-GCM',
178
+ description: 'Use AES-256-GCM for encryption',
179
+ severity: 'LOW',
180
+ fix: 'Use crypto.createCipheriv("aes-256-gcm", key, iv)',
181
+ documentationLink: 'https://nodejs.org/api/crypto.html#cryptocreatecipherivalgorithm-key-iv-options',
182
+ }),
183
+ strategyAuto: (0, eslint_devkit_1.formatLLMMessage)({
184
+ icon: eslint_devkit_1.MessageIcons.INFO,
185
+ issueName: 'Auto-fix Strategy',
186
+ description: 'Automatically suggest the best replacement',
187
+ severity: 'LOW',
188
+ fix: 'Apply automatic fix suggestion',
189
+ documentationLink: 'https://owasp.org/www-community/vulnerabilities/Weak_Cryptography',
190
+ }),
191
+ strategyUpgrade: (0, eslint_devkit_1.formatLLMMessage)({
192
+ icon: eslint_devkit_1.MessageIcons.INFO,
193
+ issueName: 'Upgrade Strategy',
194
+ description: 'Upgrade to a stronger algorithm',
195
+ severity: 'LOW',
196
+ fix: 'Replace weak algorithm with stronger alternative',
197
+ documentationLink: 'https://owasp.org/www-community/vulnerabilities/Weak_Cryptography',
198
+ }),
199
+ strategyMigrate: (0, eslint_devkit_1.formatLLMMessage)({
200
+ icon: eslint_devkit_1.MessageIcons.INFO,
201
+ issueName: 'Migration Strategy',
202
+ description: 'Plan migration to stronger cryptography',
203
+ severity: 'LOW',
204
+ fix: 'Create migration plan for cryptographic upgrade',
205
+ documentationLink: 'https://owasp.org/www-community/vulnerabilities/Weak_Cryptography',
206
+ }),
207
+ strategyPolicy: (0, eslint_devkit_1.formatLLMMessage)({
208
+ icon: eslint_devkit_1.MessageIcons.INFO,
209
+ issueName: 'Policy Strategy',
210
+ description: 'Apply organizational security policy',
211
+ severity: 'LOW',
212
+ fix: 'crypto.createCipheriv("aes-256-gcm", key, iv)',
213
+ documentationLink: 'https://nodejs.org/api/crypto.html#cryptocreatecipherivalgorithm-key-iv-options',
214
+ }),
215
+ },
216
+ schema: [
217
+ {
218
+ type: 'object',
219
+ properties: {
220
+ allowInTests: {
221
+ type: 'boolean',
222
+ default: false,
223
+ description: 'Allow weak crypto in test files',
224
+ },
225
+ additionalWeakAlgorithms: {
226
+ type: 'array',
227
+ items: { type: 'string' },
228
+ default: [],
229
+ description: 'Additional weak algorithms to detect',
230
+ },
231
+ trustedLibraries: {
232
+ type: 'array',
233
+ items: { type: 'string' },
234
+ default: ['crypto', 'crypto-js'],
235
+ description: 'Trusted crypto libraries',
236
+ },
237
+ },
238
+ additionalProperties: false,
239
+ },
240
+ ],
241
+ },
242
+ defaultOptions: [
243
+ {
244
+ allowInTests: false,
245
+ additionalWeakAlgorithms: [],
246
+ trustedLibraries: ['crypto', 'crypto-js'],
247
+ },
248
+ ],
249
+ create(context, [options = {}]) {
250
+ const { allowInTests = false, additionalWeakAlgorithms = [], trustedLibraries = ['crypto', 'crypto-js'], } = options;
251
+ const filename = context.getFilename();
252
+ const isTestFile = allowInTests && /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(filename);
253
+ /**
254
+ * Check if a call expression uses weak crypto
255
+ */
256
+ function checkCallExpression(node) {
257
+ if (isTestFile) {
258
+ return;
259
+ }
260
+ // Check for crypto.createHash, crypto.createCipher, etc.
261
+ if (node.callee.type === 'MemberExpression') {
262
+ // Check if it's a crypto method call (e.g., crypto.createHash, crypto.createCipher)
263
+ if (node.callee.object.type === 'Identifier' &&
264
+ node.callee.property.type === 'Identifier') {
265
+ const objectName = node.callee.object.name;
266
+ const methodName = node.callee.property.name;
267
+ // Check if it's a crypto method from a trusted library
268
+ const isCryptoMethod = (methodName === 'createHash' ||
269
+ methodName === 'createCipher' ||
270
+ methodName === 'createCipheriv') &&
271
+ (trustedLibraries.includes(objectName) || objectName === 'crypto');
272
+ if (isCryptoMethod) {
273
+ // Check arguments for weak algorithms
274
+ for (const arg of node.arguments) {
275
+ if (arg.type === 'Literal' && typeof arg.value === 'string') {
276
+ const weakPattern = containsWeakCrypto(arg.value, additionalWeakAlgorithms);
277
+ if (weakPattern) {
278
+ const safeAlternative = weakPattern.alternatives[0];
279
+ const refactoringSteps = generateRefactoringSteps(weakPattern, 'data');
280
+ context.report({
281
+ node: arg,
282
+ messageId: 'weakCrypto',
283
+ data: {
284
+ algorithm: weakPattern.name,
285
+ safeAlternative: `Use ${safeAlternative}: ${weakPattern.example.good}`,
286
+ },
287
+ suggest: refactoringSteps.map(step => ({
288
+ messageId: step.messageId,
289
+ fix: (fixer) => {
290
+ // Replace the weak algorithm with a safe one
291
+ if (weakPattern.category === 'hash') {
292
+ return fixer.replaceText(arg, `"sha256"`);
293
+ }
294
+ else if (weakPattern.category === 'encryption') {
295
+ return fixer.replaceText(arg, `"aes-256-gcm"`);
296
+ }
297
+ return null;
298
+ },
299
+ })),
300
+ });
301
+ }
302
+ }
303
+ }
304
+ }
305
+ }
306
+ }
307
+ // Check for standalone crypto function calls (e.g., createHash, createCipher)
308
+ if (node.callee.type === 'Identifier') {
309
+ const calleeName = node.callee.name;
310
+ // Check for common crypto library patterns
311
+ if (calleeName === 'createHash' || calleeName === 'createCipher' || calleeName === 'createCipheriv') {
312
+ for (const arg of node.arguments) {
313
+ if (arg.type === 'Literal' && typeof arg.value === 'string') {
314
+ const weakPattern = containsWeakCrypto(arg.value, additionalWeakAlgorithms);
315
+ if (weakPattern) {
316
+ const safeAlternative = weakPattern.alternatives[0];
317
+ context.report({
318
+ node: arg,
319
+ messageId: 'weakCrypto',
320
+ data: {
321
+ algorithm: weakPattern.name,
322
+ safeAlternative: `Use ${safeAlternative}: ${weakPattern.example.good}`,
323
+ },
324
+ suggest: [
325
+ {
326
+ messageId: weakPattern.category === 'hash' ? 'useSha256' : 'useAes256',
327
+ fix: (fixer) => {
328
+ if (weakPattern.category === 'hash') {
329
+ return fixer.replaceText(arg, `"sha256"`);
330
+ }
331
+ else if (weakPattern.category === 'encryption') {
332
+ return fixer.replaceText(arg, `"aes-256-gcm"`);
333
+ }
334
+ return null;
335
+ },
336
+ },
337
+ ],
338
+ });
339
+ }
340
+ }
341
+ }
342
+ }
343
+ }
344
+ }
345
+ return {
346
+ CallExpression: checkCallExpression,
347
+ };
348
+ },
349
+ });
350
+ //# sourceMappingURL=no-weak-crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-weak-crypto.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-secure-coding/src/rules/security/no-weak-crypto.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type SecurityRuleOptions } from '@interlace/eslint-devkit';
2
+ export interface Options extends SecurityRuleOptions {
3
+ /** Minimum token entropy bits */
4
+ minTokenEntropy?: number;
5
+ /** Maximum token lifetime in hours */
6
+ maxTokenLifetimeHours?: number;
7
+ /** Recovery-related keywords */
8
+ recoveryKeywords?: string[];
9
+ /** Secure token generation functions */
10
+ secureTokenFunctions?: string[];
11
+ }
12
+ export declare const noWeakPasswordRecovery: ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;