Files

48 lines
1.3 KiB
JavaScript

import path from "node:path";
import {
readTextFileIfSmall,
relative,
walkFiles,
} from "./repository-files.mjs";
const patterns = [
["private key block", /-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/u],
["GitHub token", /\bgh[pousr]_[A-Za-z0-9]{30,}\b/u],
["OpenAI-style key", /\bsk-[A-Za-z0-9_-]{20,}\b/u],
["Google API key", /\bAIza[0-9A-Za-z_-]{35}\b/u],
["AWS access key", /\bAKIA[0-9A-Z]{16}\b/u],
];
const excludedExtensions = new Set([
".gif",
".ico",
".jpeg",
".jpg",
".pdf",
".png",
".webp",
".zip",
]);
const findings = [];
for (const file of await walkFiles()) {
if (excludedExtensions.has(path.extname(file).toLowerCase())) continue;
const content = await readTextFileIfSmall(file);
if (content === null) continue;
for (const [label, pattern] of patterns) {
const match = pattern.exec(content);
if (!match) continue;
const line = content.slice(0, match.index).split(/\r?\n/u).length;
findings.push(`${relative(file)}:${line} (${label})`);
}
}
if (findings.length > 0) {
console.error("Potential secrets found; values are intentionally redacted:");
for (const finding of findings) console.error(`- ${finding}`);
process.exitCode = 1;
} else {
console.log("High-confidence secret scan passed.");
}