mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-11 07:29:00 +02:00
test: pin the security-property regression guards from pre-landing review
The pre-landing review found the fixes were correct but three regression guards were missing — each pins a property whose silent revert would keep behavior identical while reopening the hole: - validateAuth: a static tripwire asserting crypto.timingSafeEqual + the got.length===want.length gate + the null-header guard (a revert to `===` keeps accept/reject green but restores the timing side-channel). - redact: a table-driven loop over the exported URL_PASSWORD_PLACEHOLDER_WORDS so a typo or dropped entry can't silently start blocking a doc placeholder; plus a substring-can't-rescue-a-real-secret assertion. - config: assert the self-contained .gitignore is written even when git already ignores .gstack/, proving the write precedes the isIgnoredByGit early return. - bun-polyfill: cover the 128+signal exit branch (POSIX only). URL_PASSWORD_PLACEHOLDER_WORDS is exported so the table test can't drift. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
341d7be27c
commit
5d74ed7231
@@ -21,6 +21,7 @@ import {
|
||||
shannonEntropy,
|
||||
isPublicIPv4,
|
||||
isPlaceholderSpan,
|
||||
URL_PASSWORD_PLACEHOLDER_WORDS,
|
||||
} from "../lib/redact-patterns";
|
||||
|
||||
function ids(text: string, vis: RepoVisibility = "private"): string[] {
|
||||
@@ -143,6 +144,21 @@ describe("HIGH credential patterns", () => {
|
||||
expect(ids("postgres://admin:" + "ADMIN" + "123@host/db")).toContain("db.url_with_password");
|
||||
});
|
||||
|
||||
// Every curated placeholder word must suppress at the URL-password position.
|
||||
// The fix replaced a shape rule with a hand-curated EXACT set, so a typo or a
|
||||
// dropped entry (CHANGEME -> CHANGME) would silently start blocking a legit
|
||||
// doc placeholder with zero failure elsewhere. Loop the real exported set so
|
||||
// the test can't drift from the source list.
|
||||
test("db.url_with_password suppresses every curated placeholder word", () => {
|
||||
for (const word of URL_PASSWORD_PLACEHOLDER_WORDS) {
|
||||
expect(ids(`postgres://user:${word}@host/db`)).not.toContain("db.url_with_password");
|
||||
}
|
||||
// Guard the set stays a non-trivial curated list (catches an accidental clear).
|
||||
expect(URL_PASSWORD_PLACEHOLDER_WORDS.size).toBeGreaterThanOrEqual(8);
|
||||
// And a real secret that merely CONTAINS a placeholder word still blocks.
|
||||
expect(ids("postgres://user:" + "MY" + "SECRETPASS@host/db")).toContain("db.url_with_password");
|
||||
});
|
||||
|
||||
test("all HIGH patterns block (exit 3)", () => {
|
||||
const r = scan("AKIA1234567890ABCDEF", { repoVisibility: "private" });
|
||||
expect(exitCodeFor(r)).toBe(3);
|
||||
|
||||
Reference in New Issue
Block a user