fix: cover every tracked release input
This commit is contained in:
+18
-42
@@ -1,4 +1,3 @@
|
||||
import { createHash } from "node:crypto";
|
||||
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
@@ -6,13 +5,12 @@ import {
|
||||
buildRepositoryFileInventory,
|
||||
parseRepositoryFileInventoryPolicy,
|
||||
} from "./lib/repository-file-inventory.ts";
|
||||
import {
|
||||
findSecretMatches,
|
||||
secretScanRules,
|
||||
type SecretFinding,
|
||||
} from "./lib/secret-scan.ts";
|
||||
|
||||
type SecretFinding = Readonly<{
|
||||
ruleId: string;
|
||||
file: string;
|
||||
line: number;
|
||||
fingerprint: string;
|
||||
}>;
|
||||
type AllowlistEntry = Readonly<{
|
||||
path: string;
|
||||
ruleId: string;
|
||||
@@ -25,6 +23,7 @@ type SecretPolicy = Readonly<{
|
||||
trackedRoots: readonly string[];
|
||||
generatedRoots: readonly string[];
|
||||
optionalRoots: readonly string[];
|
||||
includedPaths: readonly string[];
|
||||
allowlist: readonly AllowlistEntry[];
|
||||
}>;
|
||||
|
||||
@@ -66,6 +65,7 @@ function parsePolicy(value: unknown): SecretPolicy {
|
||||
trackedRoots: inventoryPolicy.trackedRoots,
|
||||
generatedRoots: inventoryPolicy.generatedRoots,
|
||||
optionalRoots: inventoryPolicy.optionalRoots,
|
||||
includedPaths: Object.freeze(strings(document.includedPaths)),
|
||||
allowlist: Object.freeze(allowlist),
|
||||
});
|
||||
}
|
||||
@@ -82,23 +82,14 @@ const rawPolicy: unknown = JSON.parse(await readFile(policyPath, "utf8"));
|
||||
const policy = parsePolicy(rawPolicy);
|
||||
const findings: SecretFinding[] = [];
|
||||
const policyFailures: string[] = [];
|
||||
const patterns: readonly Readonly<{ id: string; expression: RegExp }>[] = [
|
||||
{
|
||||
id: "private-key",
|
||||
expression: /-----BEGIN (?:RSA |EC )?PRIVATE KEY-----/g,
|
||||
},
|
||||
{ id: "aws-access-key", expression: /\bAKIA[0-9A-Z]{16}\b/g },
|
||||
{ id: "github-token", expression: /\bgh[pousr]_[A-Za-z0-9_]{30,}\b/g },
|
||||
{
|
||||
id: "assigned-secret",
|
||||
expression:
|
||||
/\b(?:client_secret|password|private_key)\s*[:=]\s*["'][^"'${}]{12,}["']/gi,
|
||||
},
|
||||
];
|
||||
const patterns = secretScanRules();
|
||||
|
||||
const excluded = new Set(
|
||||
policy.excludedPaths.map((entry) => entry.replaceAll("\\", "/")),
|
||||
);
|
||||
const included = policy.includedPaths.map((entry) =>
|
||||
entry.replaceAll("\\", "/"),
|
||||
);
|
||||
const allowlist = policy.allowlist;
|
||||
for (const entry of allowlist) {
|
||||
const expiry = Date.parse(entry.expiresAt);
|
||||
@@ -124,6 +115,10 @@ const scanFiles = inventory.files;
|
||||
for (const scanFile of [...new Set(scanFiles)].sort()) {
|
||||
const normalized = scanFile.replaceAll("\\", "/");
|
||||
if (
|
||||
(included.length > 0 &&
|
||||
!included.some(
|
||||
(entry) => normalized === entry || normalized.startsWith(`${entry}/`),
|
||||
)) ||
|
||||
[...excluded].some(
|
||||
(entry) => normalized === entry || normalized.startsWith(`${entry}/`),
|
||||
) ||
|
||||
@@ -132,28 +127,9 @@ for (const scanFile of [...new Set(scanFiles)].sort()) {
|
||||
continue;
|
||||
}
|
||||
const content = await readFile(scanFile, "utf8");
|
||||
for (const pattern of patterns) {
|
||||
pattern.expression.lastIndex = 0;
|
||||
for (const match of content.matchAll(pattern.expression)) {
|
||||
const isAllowed = allowlist.some(
|
||||
(entry) =>
|
||||
entry.path === normalized &&
|
||||
entry.ruleId === pattern.id &&
|
||||
Date.parse(entry.expiresAt) > Date.now(),
|
||||
);
|
||||
if (isAllowed) continue;
|
||||
const matchIndex = match.index ?? 0;
|
||||
const prefix = content.slice(0, matchIndex);
|
||||
findings.push({
|
||||
ruleId: pattern.id,
|
||||
file: normalized,
|
||||
line: prefix.split(/\r?\n/).length,
|
||||
fingerprint: createHash("sha256")
|
||||
.update(`${pattern.id}:${normalized}:${String(matchIndex)}`)
|
||||
.digest("hex"),
|
||||
});
|
||||
}
|
||||
}
|
||||
findings.push(
|
||||
...findSecretMatches(normalized, content, { allowlist }),
|
||||
);
|
||||
}
|
||||
|
||||
const sarif = {
|
||||
|
||||
Reference in New Issue
Block a user