fix(redact): block real all-caps URL passwords, not just shape-match

urlPasswordIsPlaceholder skipped any password matching /^[A-Z][A-Z0-9_]*$/,
so a real DSN like postgres://admin:PROD2026SECRET@db-prod.internal/app slipped
the HIGH pre-push block. Replace the shape rule with an anchored, exact-match
set of doc-convention placeholder tokens (PASSWORD, PASS, CHANGEME, ...),
compared case-sensitively and never as a substring (PROD2026SECRET must not
match SECRET). The USER:PASSWORD doc convention still suppresses; real all-caps
and lowercase passwords block. Regression cases pinned both directions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-08-16 10:14:32 -07:00
co-authored by Claude Fable 5
parent 410b4928e7
commit 57a1d957f4
2 changed files with 29 additions and 6 deletions
+7
View File
@@ -134,6 +134,13 @@ describe("HIGH credential patterns", () => {
expect(ids("https://root:" + "pa" + "ss@127.0.0.1/")).toContain("creds.basic_auth_url");
// Structural placeholders still suppress at the URL position.
expect(ids("postgres://user:<your-password>@host/db")).not.toContain("db.url_with_password");
// An ALL-CAPS password that is NOT an exact placeholder token is a real
// secret and must block — the pre-fix shape rule (/^[A-Z][A-Z0-9_]*$/) waved
// every all-caps password through. Substring of a placeholder word (SECRET)
// must not rescue it. Assembled at runtime so this file's own pushed bytes
// carry no live DSN shape.
expect(ids("postgres://admin:" + "PROD2026" + "SECRET@db-prod.internal/app")).toContain("db.url_with_password");
expect(ids("postgres://admin:" + "ADMIN" + "123@host/db")).toContain("db.url_with_password");
});
test("all HIGH patterns block (exit 3)", () => {