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,377 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.noHardcodedCredentials = void 0;
4
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
5
+ const eslint_devkit_2 = require("@interlace/eslint-devkit");
6
+ /**
7
+ * Common credential patterns
8
+ */
9
+ const CREDENTIAL_PATTERNS = {
10
+ // API Keys (typically 32+ character alphanumeric strings)
11
+ apiKey: /^(?:[A-Za-z0-9_-]{32,}|sk_[A-Za-z0-9_-]{32,}|pk_[A-Za-z0-9_-]{32,}|AKIA[0-9A-Z]{16})$/,
12
+ // JWT Tokens (three base64 parts separated by dots)
13
+ jwtToken: /^eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/,
14
+ // OAuth tokens
15
+ oauthToken: /^(?:ghp_|gho_|ghu_|ghs_|ghr_)[A-Za-z0-9]{36,}$/,
16
+ // AWS Access Keys
17
+ awsAccessKey: /^AKIA[0-9A-Z]{16}$/,
18
+ // Database connection strings with credentials
19
+ databaseString: /^(?:mysql|postgres|mongodb|redis):\/\/[^:]+:[^@]+@/,
20
+ // Generic password patterns (common weak passwords) - no length requirement
21
+ commonPassword: /^(?:password|admin|123456|qwerty|letmein|welcome|monkey|1234567890|12345678|password123|root|test|guest)$/i,
22
+ // Secret keys (base64-like or hex strings)
23
+ secretKey: /^(?:[A-Za-z0-9+/]{32,}={0,2}|[A-Fa-f0-9]{32,})$/,
24
+ };
25
+ // Note: CREDENTIAL_VARIABLE_NAMES is reserved for future use when we want to
26
+ // check variable names in addition to values
27
+ // @coverage-note: Not currently used, reserved for future enhancement
28
+ /**
29
+ * Check if a string literal looks like a hardcoded credential
30
+ */
31
+ function looksLikeCredential(value, options, ignorePatterns) {
32
+ // Check ignore patterns first
33
+ if (ignorePatterns.some(pattern => pattern.test(value))) {
34
+ return { isCredential: false, type: '' };
35
+ }
36
+ // Check custom patterns first (highest priority)
37
+ for (const customPattern of options.customPatterns) {
38
+ try {
39
+ const regex = new RegExp(customPattern.pattern);
40
+ if (regex.test(value)) {
41
+ return { isCredential: true, type: customPattern.type };
42
+ }
43
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
44
+ }
45
+ catch (error) {
46
+ // Invalid regex pattern, skip it
47
+ continue;
48
+ }
49
+ }
50
+ // Check passwords (common weak passwords) - no length requirement, check first
51
+ if (options.detectPasswords) {
52
+ if (CREDENTIAL_PATTERNS.commonPassword.test(value)) {
53
+ return { isCredential: true, type: 'Common password' };
54
+ }
55
+ }
56
+ // Check database connection strings - no length requirement
57
+ if (options.detectDatabaseStrings) {
58
+ if (CREDENTIAL_PATTERNS.databaseString.test(value)) {
59
+ return { isCredential: true, type: 'Database connection string' };
60
+ }
61
+ }
62
+ // Check minimum length for other patterns
63
+ if (value.length < options.minLength) {
64
+ return { isCredential: false, type: '' };
65
+ }
66
+ // Check tokens first (more specific patterns)
67
+ if (options.detectTokens) {
68
+ if (CREDENTIAL_PATTERNS.jwtToken.test(value)) {
69
+ return { isCredential: true, type: 'JWT token' };
70
+ }
71
+ if (CREDENTIAL_PATTERNS.oauthToken.test(value)) {
72
+ return { isCredential: true, type: 'OAuth token' };
73
+ }
74
+ }
75
+ // Check secret keys first (before generic API key patterns)
76
+ if (value.length >= 32 && CREDENTIAL_PATTERNS.secretKey.test(value)) {
77
+ return { isCredential: true, type: 'Secret key' };
78
+ }
79
+ // Check API keys
80
+ if (options.detectApiKeys) {
81
+ if (CREDENTIAL_PATTERNS.awsAccessKey.test(value)) {
82
+ return { isCredential: true, type: 'AWS access key' };
83
+ }
84
+ // Generic API key pattern (long alphanumeric strings)
85
+ if (/^[A-Za-z0-9_-]{32,}$/.test(value)) {
86
+ return { isCredential: true, type: 'API key' };
87
+ }
88
+ }
89
+ return { isCredential: false, type: '' };
90
+ }
91
+ // Note: isCredentialVariableName is reserved for future use when we want to
92
+ // check variable names in addition to values
93
+ // @coverage-note: Not currently used, reserved for future enhancement
94
+ exports.noHardcodedCredentials = (0, eslint_devkit_2.createRule)({
95
+ name: 'no-hardcoded-credentials',
96
+ meta: {
97
+ type: 'problem',
98
+ docs: {
99
+ description: 'Detects hardcoded passwords, API keys, tokens, and other sensitive credentials',
100
+ },
101
+ fixable: 'code',
102
+ hasSuggestions: true,
103
+ messages: {
104
+ useEnvironmentVariable: (0, eslint_devkit_1.formatLLMMessage)({
105
+ icon: eslint_devkit_1.MessageIcons.SECURITY,
106
+ issueName: 'Hard-coded Credential',
107
+ cwe: 'CWE-798',
108
+ description: 'Hard-coded {{credentialType}} detected',
109
+ severity: 'CRITICAL',
110
+ fix: 'Use environment variable: process.env.{{envVarName}} or secret management service',
111
+ documentationLink: 'https://cwe.mitre.org/data/definitions/798.html',
112
+ }),
113
+ useSecretManager: (0, eslint_devkit_1.formatLLMMessage)({
114
+ icon: eslint_devkit_1.MessageIcons.SECURITY,
115
+ issueName: 'Use Secret Manager',
116
+ cwe: 'CWE-798',
117
+ description: 'Use secure secret management service',
118
+ severity: 'HIGH',
119
+ fix: 'Use AWS Secrets Manager, HashiCorp Vault, Azure Key Vault, or similar',
120
+ documentationLink: 'https://cwe.mitre.org/data/definitions/798.html',
121
+ }),
122
+ strategyEnv: (0, eslint_devkit_1.formatLLMMessage)({
123
+ icon: eslint_devkit_1.MessageIcons.DEVELOPMENT,
124
+ issueName: 'Environment Variable Strategy',
125
+ description: 'Move credentials to environment variables',
126
+ severity: 'MEDIUM',
127
+ fix: 'Store credentials in environment variables (process.env)',
128
+ documentationLink: 'https://12factor.net/config',
129
+ }),
130
+ strategyConfig: (0, eslint_devkit_1.formatLLMMessage)({
131
+ icon: eslint_devkit_1.MessageIcons.DEVELOPMENT,
132
+ issueName: 'Configuration File Strategy',
133
+ description: 'Store credentials in encrypted configuration files',
134
+ severity: 'MEDIUM',
135
+ fix: 'Use encrypted configuration files with proper access controls',
136
+ documentationLink: 'https://owasp.org/www-project-cheat-sheets/cheatsheets/Configuration_Management_Cheat_Sheet.html',
137
+ }),
138
+ strategyVault: (0, eslint_devkit_1.formatLLMMessage)({
139
+ icon: eslint_devkit_1.MessageIcons.SECURITY,
140
+ issueName: 'Secret Vault Strategy',
141
+ cwe: 'CWE-798',
142
+ description: 'Use dedicated secret management system',
143
+ severity: 'HIGH',
144
+ fix: 'Implement HashiCorp Vault, AWS Secrets Manager, or similar secret vault',
145
+ documentationLink: 'https://cwe.mitre.org/data/definitions/798.html',
146
+ }),
147
+ strategyAuto: (0, eslint_devkit_1.formatLLMMessage)({
148
+ icon: eslint_devkit_1.MessageIcons.DEVELOPMENT,
149
+ issueName: 'Context-Aware Strategy',
150
+ description: 'Apply context-aware credential management',
151
+ severity: 'MEDIUM',
152
+ fix: 'Choose strategy based on deployment environment and security requirements',
153
+ documentationLink: 'https://owasp.org/www-project-cheat-sheets/cheatsheets/Secrets_Management_Cheat_Sheet.html',
154
+ }),
155
+ },
156
+ schema: [
157
+ {
158
+ type: 'object',
159
+ properties: {
160
+ ignorePatterns: {
161
+ type: 'array',
162
+ items: { type: 'string' },
163
+ default: [],
164
+ description: 'Regex patterns to ignore',
165
+ },
166
+ allowInTests: {
167
+ type: 'boolean',
168
+ default: false,
169
+ description: 'Allow credentials in test files',
170
+ },
171
+ minLength: {
172
+ type: 'number',
173
+ default: 8,
174
+ description: 'Minimum length for credential detection',
175
+ },
176
+ detectApiKeys: {
177
+ type: 'boolean',
178
+ default: true,
179
+ description: 'Detect API keys',
180
+ },
181
+ detectPasswords: {
182
+ type: 'boolean',
183
+ default: true,
184
+ description: 'Detect passwords',
185
+ },
186
+ detectTokens: {
187
+ type: 'boolean',
188
+ default: true,
189
+ description: 'Detect tokens',
190
+ },
191
+ detectDatabaseStrings: {
192
+ type: 'boolean',
193
+ default: true,
194
+ description: 'Detect database connection strings',
195
+ },
196
+ customPatterns: {
197
+ type: 'array',
198
+ items: {
199
+ type: 'object',
200
+ properties: {
201
+ type: {
202
+ type: 'string',
203
+ description: 'The type of credential (e.g., "API key", "token")',
204
+ },
205
+ pattern: {
206
+ type: 'string',
207
+ description: 'Regex pattern to match',
208
+ },
209
+ },
210
+ required: ['type', 'pattern'],
211
+ additionalProperties: false,
212
+ },
213
+ default: [],
214
+ description: 'Custom credential patterns to detect',
215
+ },
216
+ strategy: {
217
+ type: 'string',
218
+ enum: ['env', 'config', 'vault', 'auto'],
219
+ default: 'auto',
220
+ description: 'Strategy for fixing hardcoded credentials (auto = smart detection)'
221
+ },
222
+ },
223
+ additionalProperties: false,
224
+ },
225
+ ],
226
+ },
227
+ defaultOptions: [
228
+ {
229
+ ignorePatterns: [],
230
+ allowInTests: false,
231
+ minLength: 8,
232
+ detectApiKeys: true,
233
+ detectPasswords: true,
234
+ detectTokens: true,
235
+ detectDatabaseStrings: true,
236
+ customPatterns: [],
237
+ strategy: 'auto',
238
+ },
239
+ ],
240
+ create(context) {
241
+ const options = context.options[0] || {};
242
+ const { ignorePatterns = [], allowInTests = false, minLength = 8, detectApiKeys = true, detectPasswords = true, detectTokens = true, detectDatabaseStrings = true, customPatterns = [], } = options || {};
243
+ const filename = context.filename || context.getFilename();
244
+ const isTestFile = allowInTests && (filename.includes('.test.') ||
245
+ filename.includes('.spec.') ||
246
+ filename.includes('__tests__') ||
247
+ filename.includes('/test/'));
248
+ // Compile ignore patterns to regex
249
+ const compiledIgnorePatterns = ignorePatterns.map((pattern) => new RegExp(pattern));
250
+ const detectionOptions = {
251
+ minLength,
252
+ detectApiKeys,
253
+ detectPasswords,
254
+ detectTokens,
255
+ detectDatabaseStrings,
256
+ customPatterns,
257
+ };
258
+ /**
259
+ * Check a string literal node
260
+ */
261
+ function checkStringLiteral(node, parent) {
262
+ if (typeof node.value !== 'string') {
263
+ return;
264
+ }
265
+ const value = node.value;
266
+ // Skip if in test files and allowed
267
+ if (isTestFile) {
268
+ return;
269
+ }
270
+ // Check if it looks like a credential
271
+ const { isCredential, type } = looksLikeCredential(value, detectionOptions, compiledIgnorePatterns);
272
+ if (!isCredential) {
273
+ return;
274
+ }
275
+ // Generate environment variable name suggestion
276
+ let envVarName = 'API_KEY';
277
+ if (parent && parent.type === 'Property' && parent.key.type === 'Identifier') {
278
+ const keyName = parent.key.name;
279
+ envVarName = keyName
280
+ .replace(/([a-z])([A-Z])/g, '$1_$2')
281
+ .toUpperCase()
282
+ .replace(/[^A-Z0-9_]/g, '_');
283
+ }
284
+ else if (parent && parent.type === 'VariableDeclarator' && parent.id.type === 'Identifier') {
285
+ const varName = parent.id.name;
286
+ envVarName = varName
287
+ .replace(/([a-z])([A-Z])/g, '$1_$2')
288
+ .toUpperCase()
289
+ .replace(/[^A-Z0-9_]/g, '_');
290
+ }
291
+ context.report({
292
+ node,
293
+ messageId: 'useEnvironmentVariable',
294
+ data: {
295
+ credentialType: type,
296
+ envVarName,
297
+ },
298
+ suggest: [
299
+ {
300
+ messageId: 'useEnvironmentVariable',
301
+ data: { envVarName, credentialType: type },
302
+ fix: (fixer) => {
303
+ return fixer.replaceText(node, `process.env.${envVarName} || '${value}'`);
304
+ },
305
+ },
306
+ {
307
+ messageId: 'useSecretManager',
308
+ data: { credentialType: type },
309
+ fix: (fixer) => {
310
+ return fixer.replaceText(node, `await getSecret('${envVarName.toLowerCase()}')`);
311
+ },
312
+ },
313
+ ],
314
+ });
315
+ }
316
+ return {
317
+ Literal(node) {
318
+ checkStringLiteral(node, node.parent);
319
+ },
320
+ TemplateLiteral(node) {
321
+ // Check template literal parts for credentials
322
+ // Only check if there are no interpolations (static template literal)
323
+ if (node.expressions.length === 0) {
324
+ const fullText = node.quasis.map((q) => q.value.raw).join('');
325
+ const { isCredential, type } = looksLikeCredential(fullText, detectionOptions, compiledIgnorePatterns);
326
+ if (isCredential && !isTestFile) {
327
+ context.report({
328
+ node,
329
+ messageId: 'useEnvironmentVariable',
330
+ data: {
331
+ credentialType: type,
332
+ envVarName: 'API_KEY',
333
+ },
334
+ suggest: [
335
+ {
336
+ messageId: 'useEnvironmentVariable',
337
+ data: { envVarName: 'API_KEY', credentialType: type },
338
+ fix: (fixer) => {
339
+ return fixer.replaceText(node, `process.env.API_KEY || \`${fullText}\``);
340
+ },
341
+ },
342
+ {
343
+ messageId: 'useSecretManager',
344
+ data: { credentialType: type },
345
+ fix: (fixer) => {
346
+ return fixer.replaceText(node, `await getSecret('api_key')`);
347
+ },
348
+ },
349
+ ],
350
+ });
351
+ }
352
+ }
353
+ else {
354
+ // For template literals with interpolations, check each quasi part
355
+ for (const quasi of node.quasis) {
356
+ if (quasi.value.raw) {
357
+ const { isCredential, type } = looksLikeCredential(quasi.value.raw, detectionOptions, compiledIgnorePatterns);
358
+ if (isCredential && !isTestFile) {
359
+ // Note: Template literals with interpolations are complex to fix automatically
360
+ // So we report the error without suggestions
361
+ context.report({
362
+ node: quasi,
363
+ messageId: 'useEnvironmentVariable',
364
+ data: {
365
+ credentialType: type,
366
+ envVarName: 'API_KEY',
367
+ },
368
+ });
369
+ }
370
+ }
371
+ }
372
+ }
373
+ },
374
+ };
375
+ },
376
+ });
377
+ //# sourceMappingURL=no-hardcoded-credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-hardcoded-credentials.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-secure-coding/src/rules/security/no-hardcoded-credentials.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
+ /** Safe sanitization functions */
4
+ safeSanitizers?: string[];
5
+ /** Characters that should be escaped */
6
+ dangerousChars?: string[];
7
+ /** Contexts that require different encoding */
8
+ contexts?: string[];
9
+ /** Trusted sanitization libraries */
10
+ trustedLibraries?: string[];
11
+ }
12
+ export declare const noImproperSanitization: ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;