chore: initialize from frontend template 4dc033c
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
import { createHash } from "node:crypto";
|
||||
|
||||
export type SecretFinding = Readonly<{
|
||||
ruleId: string;
|
||||
file: string;
|
||||
line: number;
|
||||
fingerprint: string;
|
||||
}>;
|
||||
|
||||
export type SecretAllowlistEntry = Readonly<{
|
||||
path: string;
|
||||
ruleId: string;
|
||||
expiresAt: string;
|
||||
}>;
|
||||
|
||||
const secretPatterns: 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:
|
||||
/(?<![\w])(["']?)(?:client_secret|password|private_key)\1(?![\w])\s*[:=]\s*["'][^"'${}]{12,}["']/gi,
|
||||
},
|
||||
];
|
||||
|
||||
export function secretScanRules(): readonly Readonly<{
|
||||
id: string;
|
||||
expression: RegExp;
|
||||
}>[] {
|
||||
return secretPatterns;
|
||||
}
|
||||
|
||||
export function findSecretMatches(
|
||||
file: string,
|
||||
content: string,
|
||||
options: Readonly<{
|
||||
allowlist?: readonly SecretAllowlistEntry[];
|
||||
now?: number;
|
||||
}> = {},
|
||||
): SecretFinding[] {
|
||||
const allowlist = options.allowlist ?? [];
|
||||
const now = options.now ?? Date.now();
|
||||
const findings: SecretFinding[] = [];
|
||||
for (const pattern of secretPatterns) {
|
||||
pattern.expression.lastIndex = 0;
|
||||
for (const match of content.matchAll(pattern.expression)) {
|
||||
const isAllowed = allowlist.some(
|
||||
(entry) =>
|
||||
entry.path === file &&
|
||||
entry.ruleId === pattern.id &&
|
||||
Date.parse(entry.expiresAt) > now,
|
||||
);
|
||||
if (isAllowed) continue;
|
||||
const matchIndex = match.index ?? 0;
|
||||
findings.push({
|
||||
ruleId: pattern.id,
|
||||
file,
|
||||
line: content.slice(0, matchIndex).split(/\r?\n/u).length,
|
||||
fingerprint: createHash("sha256")
|
||||
.update(`${pattern.id}:${file}:${String(matchIndex)}`)
|
||||
.digest("hex"),
|
||||
});
|
||||
}
|
||||
}
|
||||
return findings;
|
||||
}
|
||||
Reference in New Issue
Block a user