env-detector 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/env-scan.js +5 -3
- package/package.json +1 -1
- package/src/scan.js +36 -5
package/bin/env-scan.js
CHANGED
|
@@ -90,9 +90,11 @@ if (securityMode) {
|
|
|
90
90
|
process.exit(0);
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
console.log("\nSecurity issues:\n");
|
|
94
|
-
issues.forEach(i =>
|
|
95
|
-
|
|
93
|
+
console.log("\nSecurity issues found:\n");
|
|
94
|
+
issues.forEach(i => {
|
|
95
|
+
console.log(` - ${i.file}:${i.line}`);
|
|
96
|
+
console.log(` ${i.snippet}\n`);
|
|
97
|
+
});
|
|
96
98
|
|
|
97
99
|
process.exit(0);
|
|
98
100
|
}
|
package/package.json
CHANGED
package/src/scan.js
CHANGED
|
@@ -215,14 +215,20 @@ function scanSecurity(rootDir) {
|
|
|
215
215
|
const issues = [];
|
|
216
216
|
|
|
217
217
|
const regex =
|
|
218
|
-
/(password|secret|token|apikey|key)\s*[:=]\s*['"][^'"]
|
|
218
|
+
/(?<![a-zA-Z0-9])(password|secret|token|apikey|key)\b\s*[:=]\s*['"](?!(string|varchar|text|number|boolean|uuid|auto_increment|primary_key|null|undefined|true|false|name|id|type|label|department|category|field|header|consumption|duration)['"])[^'"]{8,}['"]/gi;
|
|
219
219
|
|
|
220
220
|
function scan(dir) {
|
|
221
221
|
const files = fs.readdirSync(dir);
|
|
222
222
|
|
|
223
223
|
for (const file of files) {
|
|
224
224
|
|
|
225
|
-
if (
|
|
225
|
+
if (
|
|
226
|
+
file === "node_modules" ||
|
|
227
|
+
file === ".git" ||
|
|
228
|
+
file === "dist" ||
|
|
229
|
+
file === "build" ||
|
|
230
|
+
file.startsWith(".")
|
|
231
|
+
) continue;
|
|
226
232
|
|
|
227
233
|
const full = path.join(dir, file);
|
|
228
234
|
const stat = fs.statSync(full);
|
|
@@ -232,9 +238,34 @@ function scanSecurity(rootDir) {
|
|
|
232
238
|
} else if (/\.(js|ts|env)$/.test(file)) {
|
|
233
239
|
const content = fs.readFileSync(full, "utf8");
|
|
234
240
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
241
|
+
const lines = content.split("\n");
|
|
242
|
+
lines.forEach((line, index) => {
|
|
243
|
+
regex.lastIndex = 0;
|
|
244
|
+
const match = regex.exec(line);
|
|
245
|
+
if (match) {
|
|
246
|
+
const matchedWord = match[1].toLowerCase();
|
|
247
|
+
const fullMatch = match[0];
|
|
248
|
+
const valMatch = fullMatch.match(/['"](.*?)['"]/);
|
|
249
|
+
if (!valMatch) return;
|
|
250
|
+
|
|
251
|
+
const value = valMatch[1];
|
|
252
|
+
|
|
253
|
+
// Ignore paths/URLs
|
|
254
|
+
if (value.startsWith("/")) return;
|
|
255
|
+
|
|
256
|
+
// Stricter check for generic "key" property
|
|
257
|
+
if (matchedWord === "key") {
|
|
258
|
+
const hasComplexity = /[0-9!@#$%^&*()+\-=\[\]{};':"\\|,.<>\/?]/.test(value);
|
|
259
|
+
if (!hasComplexity) return;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
issues.push({
|
|
263
|
+
file: full,
|
|
264
|
+
line: index + 1,
|
|
265
|
+
snippet: line.trim()
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
});
|
|
238
269
|
}
|
|
239
270
|
}
|
|
240
271
|
}
|