mirror of https://github.com/garrytan/gstack.git
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:
parent
85954e604a
commit
a03f571147
|
|
@ -138,6 +138,36 @@ function looksLikeWallet(span: string): boolean {
|
|||
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) ─────────────────
|
||||
|
||||
/**
|
||||
|
|
@ -498,7 +528,10 @@ export const PATTERNS: RedactPattern[] = [
|
|||
autoRedactable: true,
|
||||
redactToken: "<REDACTED-PHONE>",
|
||||
// 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",
|
||||
|
|
|
|||
|
|
@ -203,8 +203,9 @@ describe("PII patterns", () => {
|
|||
scan("bob@acme.co", { repoVisibility: "private", repoPublicEmails: ["bob@acme.co"] }).findings,
|
||||
).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("backup stamp 20260727202423 ran late")).not.toContain("pii.phone.e164");
|
||||
});
|
||||
test("ssn flags valid, skips 000 octet", () => {
|
||||
expect(ids("ssn 123-45-6789")).toContain("pii.ssn");
|
||||
|
|
|
|||
Loading…
Reference in New Issue