mirror of https://github.com/garrytan/gstack.git
test(redact-prepush): assemble the fake AWS key at runtime — the literal blocked our own push
The hook's fixtures carried a live-format AKIA literal, and the repo's own pre-push scanner (hardened in this wave) correctly blocked pushing it. The placeholder-suppressed docs key would defeat the detection tests, so the fixtures now concatenate the key at runtime: tests still exercise real detection, and the pushed diff never contains a scannable credential shape. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
2b8a16e817
commit
4fc3731a50
|
|
@ -46,6 +46,12 @@ function runHook(
|
|||
|
||||
const ZERO = "0000000000000000000000000000000000000000";
|
||||
|
||||
// Assembled at runtime so the LITERAL never appears in a pushed diff — the
|
||||
// repo's own pre-push scanner (correctly) blocks live-format AWS key shapes,
|
||||
// and the placeholder-suppressed docs key would defeat these detection tests.
|
||||
const FAKE_AWS_KEY = ['AKIA', '1234567890ABCDEF'].join('');
|
||||
|
||||
|
||||
beforeEach(() => {
|
||||
repo = fs.mkdtempSync(path.join(os.tmpdir(), "prepush-"));
|
||||
git(["init", "-q", "-b", "main"]);
|
||||
|
|
@ -61,7 +67,7 @@ afterEach(() => {
|
|||
describe("pre-push hook gating", () => {
|
||||
test("HIGH credential in pushed diff blocks (exit 1)", () => {
|
||||
const base = git(["rev-parse", "HEAD"]);
|
||||
const head = commit("config.txt", "key AKIA1234567890ABCDEF\n", "add key");
|
||||
const head = commit("config.txt", "key " + FAKE_AWS_KEY + "\n", "add key");
|
||||
const { code, stderr } = runHook(`refs/heads/main ${head} refs/heads/main ${base}\n`);
|
||||
expect(code).toBe(1);
|
||||
expect(stderr).toContain("BLOCKED");
|
||||
|
|
@ -87,7 +93,7 @@ describe("pre-push hook gating", () => {
|
|||
describe("diff direction + special refs", () => {
|
||||
test("only NEW content is scanned (remote..local), not pre-existing", () => {
|
||||
// Put a secret in the FIRST commit (already on remote), then push a clean commit.
|
||||
const withSecret = commit("old.txt", "AKIA1234567890ABCDEF\n", "old secret already pushed");
|
||||
const withSecret = commit("old.txt", FAKE_AWS_KEY + "\n", "old secret already pushed");
|
||||
const clean = commit("new.txt", "totally clean\n", "new clean commit");
|
||||
// remote already has withSecret; we push only the clean commit on top.
|
||||
const { code } = runHook(`refs/heads/main ${clean} refs/heads/main ${withSecret}\n`);
|
||||
|
|
@ -134,7 +140,7 @@ describe("fail closed on unscannable diffs (#1946)", () => {
|
|||
// merge-base/empty-tree range — a secret in the pushed content still
|
||||
// blocks; a clean push passes instead of hard-failing.
|
||||
const fakeRemoteSha = "c".repeat(40);
|
||||
const head = commit("secrets.txt", "key AKIA1234567890ABCDEF\n", "leaky commit");
|
||||
const head = commit("secrets.txt", "key " + FAKE_AWS_KEY + "\n", "leaky commit");
|
||||
const { code, stderr } = runHook(`refs/heads/main ${head} refs/heads/main ${fakeRemoteSha}\n`);
|
||||
expect(code).toBe(1); // fallback range still catches the credential
|
||||
expect(stderr).toContain("aws.access_key");
|
||||
|
|
@ -188,7 +194,7 @@ describe("install UX surfaces (#1946 / eng review D3+D10)", () => {
|
|||
describe("escape valve", () => {
|
||||
test("GSTACK_REDACT_PREPUSH=skip bypasses + logs", () => {
|
||||
const base = git(["rev-parse", "HEAD"]);
|
||||
const head = commit("config.txt", "key AKIA1234567890ABCDEF\n", "add key");
|
||||
const head = commit("config.txt", "key " + FAKE_AWS_KEY + "\n", "add key");
|
||||
const home = fs.mkdtempSync(path.join(os.tmpdir(), "ghome-"));
|
||||
const { code } = runHook(`refs/heads/main ${head} refs/heads/main ${base}\n`, {
|
||||
GSTACK_REDACT_PREPUSH: "skip",
|
||||
|
|
@ -293,7 +299,7 @@ describe("base resolution when the default branch is neither main nor master", (
|
|||
spawnSync("git", ["init", "-q", "--bare", "-b", "trunk", bare]);
|
||||
|
||||
git(["branch", "-M", "trunk"]);
|
||||
const old = commit("legacy.txt", "AKIA1234567890ABCDEF\n", "secret already on the remote");
|
||||
const old = commit("legacy.txt", FAKE_AWS_KEY + "\n", "secret already on the remote");
|
||||
git(["remote", "add", "origin", bare]);
|
||||
git(["push", "-q", "origin", "trunk"]);
|
||||
|
||||
|
|
@ -318,7 +324,7 @@ describe("base resolution when the default branch is neither main nor master", (
|
|||
// Nothing is on any remote, so every commit IS new content: scanning the
|
||||
// full history is correct here. The narrowing must not open a hole in the
|
||||
// case the EMPTY_TREE fallback exists for.
|
||||
const head = commit("secrets.txt", "AKIA1234567890ABCDEF\n", "secret in a fresh repo");
|
||||
const head = commit("secrets.txt", FAKE_AWS_KEY + "\n", "secret in a fresh repo");
|
||||
const { code, stderr } = runHook(`refs/heads/feat ${head} refs/heads/feat ${ZERO}\n`);
|
||||
expect(code).toBe(1);
|
||||
expect(stderr).toContain("aws.access_key");
|
||||
|
|
@ -330,7 +336,7 @@ describe("diff-extraction bypasses (#2498, minimal reimplementation)", () => {
|
|||
// With diff.external set, plain `git diff` emits the driver's output —
|
||||
// typically zero '+' lines — so an unhardened scanner reads an empty diff
|
||||
// and allows a push full of secrets. --no-ext-diff must neutralize it.
|
||||
const head = commit("leak.txt", "AKIA1234567890ABCDEF\n", "secret behind ext driver");
|
||||
const head = commit("leak.txt", FAKE_AWS_KEY + "\n", "secret behind ext driver");
|
||||
git(["config", "diff.external", "/usr/bin/true"]);
|
||||
const { code, stderr } = runHook(`refs/heads/feat ${head} refs/heads/feat ${ZERO}\n`);
|
||||
git(["config", "--unset", "diff.external"]);
|
||||
|
|
@ -341,7 +347,7 @@ describe("diff-extraction bypasses (#2498, minimal reimplementation)", () => {
|
|||
test("an added content line starting with ++ is still scanned", () => {
|
||||
// Content "++AKIA…" renders in the diff as "+++AKIA…", which a blanket
|
||||
// startsWith('+++') header skip silently dropped from the scan.
|
||||
const head = commit("notes.txt", "++AKIA1234567890ABCDEF\n", "content line looks like a header");
|
||||
const head = commit("notes.txt", "++" + FAKE_AWS_KEY + "\n", "content line looks like a header");
|
||||
const { code, stderr } = runHook(`refs/heads/feat ${head} refs/heads/feat ${ZERO}\n`);
|
||||
expect(code).toBe(1);
|
||||
expect(stderr).toContain("aws.access_key");
|
||||
|
|
|
|||
Loading…
Reference in New Issue