mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-19 11:22:21 +02:00
fix(redact): stop the E.164 phone pattern flagging compact timestamps
Bare 14-digit runs like 20260727202423 (YYYYMMDDHHMMSS backup/log stamps) matched the phone regex and produced MEDIUM PII findings. Reject a separator-free 14-digit span whose fields parse as a plausible date-time; real numbers carry a + or spacing, so phone coverage is unchanged. Contributed by @abkrim (PR #2428). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
85954e604a
commit
a03f571147
+34
-1
@@ -138,6 +138,36 @@ function looksLikeWallet(span: string): boolean {
|
|||||||
return span.length >= 26 && span.length <= 62;
|
return span.length >= 26 && span.length <= 62;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compact log/backup stamps (`20260727202423` = YYYYMMDDHHMMSS) are bare digit
|
||||||
|
// runs that the phone regex happily eats. Only a SEPARATOR-FREE 14-digit span
|
||||||
|
// qualifies: E.164 tops out at 15 digits and real numbers carry a + or spacing,
|
||||||
|
// so rejecting this shape costs no phone coverage.
|
||||||
|
function looksLikeCompactTimestamp(span: string): boolean {
|
||||||
|
if (!/^\d{14}$/.test(span)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const n = (from: number, to: number) => Number(span.slice(from, to));
|
||||||
|
const [year, month, day, hour, minute, second] = [
|
||||||
|
n(0, 4),
|
||||||
|
n(4, 6),
|
||||||
|
n(6, 8),
|
||||||
|
n(8, 10),
|
||||||
|
n(10, 12),
|
||||||
|
n(12, 14),
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
year >= 1900 &&
|
||||||
|
year <= 2999 &&
|
||||||
|
month >= 1 &&
|
||||||
|
month <= 12 &&
|
||||||
|
day >= 1 &&
|
||||||
|
day <= 31 &&
|
||||||
|
hour <= 23 &&
|
||||||
|
minute <= 59 &&
|
||||||
|
second <= 59
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// ── Placeholder suppression (per-matched-span, NOT per-line) ─────────────────
|
// ── Placeholder suppression (per-matched-span, NOT per-line) ─────────────────
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -498,7 +528,10 @@ export const PATTERNS: RedactPattern[] = [
|
|||||||
autoRedactable: true,
|
autoRedactable: true,
|
||||||
redactToken: "<REDACTED-PHONE>",
|
redactToken: "<REDACTED-PHONE>",
|
||||||
// A digit-only UUID's hyphen groups read as national phone formatting.
|
// A digit-only UUID's hyphen groups read as national phone formatting.
|
||||||
validate: (span, match) => !insideUuid(match) && span.replace(/\D/g, "").length >= 10,
|
validate: (span, match) =>
|
||||||
|
!insideUuid(match) &&
|
||||||
|
span.replace(/\D/g, "").length >= 10 &&
|
||||||
|
!looksLikeCompactTimestamp(span),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "pii.ssn",
|
id: "pii.ssn",
|
||||||
|
|||||||
@@ -203,8 +203,9 @@ describe("PII patterns", () => {
|
|||||||
scan("bob@acme.co", { repoVisibility: "private", repoPublicEmails: ["bob@acme.co"] }).findings,
|
scan("bob@acme.co", { repoVisibility: "private", repoPublicEmails: ["bob@acme.co"] }).findings,
|
||||||
).toHaveLength(0);
|
).toHaveLength(0);
|
||||||
});
|
});
|
||||||
test("phone E.164", () => {
|
test("phone E.164 flags, skips compact timestamps", () => {
|
||||||
expect(ids("call +14155550123 now")).toContain("pii.phone.e164");
|
expect(ids("call +14155550123 now")).toContain("pii.phone.e164");
|
||||||
|
expect(ids("backup stamp 20260727202423 ran late")).not.toContain("pii.phone.e164");
|
||||||
});
|
});
|
||||||
test("ssn flags valid, skips 000 octet", () => {
|
test("ssn flags valid, skips 000 octet", () => {
|
||||||
expect(ids("ssn 123-45-6789")).toContain("pii.ssn");
|
expect(ids("ssn 123-45-6789")).toContain("pii.ssn");
|
||||||
|
|||||||
Reference in New Issue
Block a user