fix: seal P1 acceptance startup and raw Git state
This commit is contained in:
@@ -293,6 +293,30 @@ test("command helper accepts only executable plus separate argv", async () => {
|
||||
assert.equal(result.code, 0);
|
||||
});
|
||||
|
||||
test("raw runCommand rejects a configured clean filter before exact Git add", async () => {
|
||||
const repositoryRoot = await fakeRepository();
|
||||
const content = join(repositoryRoot, "workspace-content");
|
||||
const helper = join(repositoryRoot, "clean-helper");
|
||||
const marker = join(repositoryRoot, "clean-helper-ran");
|
||||
await execFileAsync("/usr/bin/git", ["init", "--initial-branch=main"], { cwd: repositoryRoot });
|
||||
await execFileAsync("/usr/bin/git", ["config", "user.name", "P1 Fixture Curator"], { cwd: repositoryRoot });
|
||||
await execFileAsync("/usr/bin/git", ["config", "user.email", "p1-curator@example.invalid"], { cwd: repositoryRoot });
|
||||
await mkdir(content);
|
||||
await writeFile(join(content, "guide.md"), "content\n");
|
||||
await writeFile(join(repositoryRoot, ".gitattributes"), "workspace-content/** filter=bad\n");
|
||||
await writeFile(helper, `#!/bin/sh\nprintf ran > '${marker}'\ncat\n`, { mode: 0o700 });
|
||||
await execFileAsync("/usr/bin/git", ["config", "filter.bad.clean", `'${helper}'`], { cwd: repositoryRoot });
|
||||
|
||||
const { gitPath } = await resolveProductionExecutables({
|
||||
repositoryRoot: await realpath(join(dirname(fileURLToPath(import.meta.url)), "..", "..")),
|
||||
});
|
||||
await assert.rejects(
|
||||
runCommand({ executable: gitPath, argv: ["add", "workspace-content"], cwd: repositoryRoot, env: process.env }),
|
||||
/unsafe Git repository state/,
|
||||
);
|
||||
await assert.rejects(lstat(marker));
|
||||
});
|
||||
|
||||
|
||||
test("safe environment rejects ambient THT and keeps only strict process allowlist plus fixture values", () => {
|
||||
const safe = buildSafeEnvironment({
|
||||
@@ -350,7 +374,7 @@ test("announce callback observes PASS and manual pending before non-keep cleanup
|
||||
test("public wrapper replaces ambient environment before invoking the runner", async () => {
|
||||
const wrapper = await readFile(join(dirname(fileURLToPath(import.meta.url)), "..", "..", "scripts", "p1-acceptance.sh"), "utf8");
|
||||
assert.match(wrapper, /safe_env=\(\/usr\/bin\/env -i/);
|
||||
assert.match(wrapper, /P1_ACCEPTANCE_FAIL_AT/);
|
||||
assert.doesNotMatch(wrapper, /P1_ACCEPTANCE_FAIL_AT|LANG|LC_ALL|TZ/);
|
||||
assert.doesNotMatch(wrapper, /export THT_BIN/);
|
||||
});
|
||||
|
||||
@@ -842,15 +866,26 @@ test("secret scan fails closed on a recoverable symlink outside fixture-secrets"
|
||||
await assert.rejects(scanSecrets({ runRoot: run.root, forbiddenValues: [canary], expectedGitRepositories: [] }), /symlink outside fixture-secrets/);
|
||||
});
|
||||
|
||||
test("direct public wrapper execution cannot source ambient BASH_ENV or ENV", async () => {
|
||||
test("direct public wrapper clears startup files and exported functions before Bash starts", async () => {
|
||||
const root = await fakeRepository();
|
||||
const startup = join(root, "startup");
|
||||
const marker = join(root, "ambient-shell-ran");
|
||||
await writeFile(startup, `printf sourced > '${marker}'\n`);
|
||||
const bashStartup = join(root, "bash-startup");
|
||||
const envStartup = join(root, "env-startup");
|
||||
const bashMarker = join(root, "bash-env-ran");
|
||||
const envMarker = join(root, "env-ran");
|
||||
const functionMarker = join(root, "exported-function-ran");
|
||||
await writeFile(bashStartup, `printf sourced > '${bashMarker}'\n`);
|
||||
await writeFile(envStartup, `printf sourced > '${envMarker}'\n`);
|
||||
const wrapper = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "scripts", "p1-acceptance.sh");
|
||||
await assert.rejects(execFileAsync(wrapper, ["invalid"], { env: { ...process.env, BASH_ENV: startup, ENV: startup } }));
|
||||
await assert.rejects(lstat(marker));
|
||||
assert.match(await readFile(wrapper, "utf8"), /^#!\/usr\/bin\/env -S -u BASH_ENV -u ENV \/bin\/bash\n/);
|
||||
await assert.rejects(execFileAsync(wrapper, ["invalid"], {
|
||||
env: {
|
||||
...process.env,
|
||||
BASH_ENV: bashStartup,
|
||||
ENV: envStartup,
|
||||
"BASH_FUNC_cd%%": `() { printf function > '${functionMarker}'; builtin cd "$@"; }`,
|
||||
},
|
||||
}));
|
||||
for (const marker of [bashMarker, envMarker, functionMarker]) await assert.rejects(lstat(marker));
|
||||
assert.match(await readFile(wrapper, "utf8"), /^#!\/usr\/bin\/env -S -i PATH=\/usr\/bin:\/bin \/bin\/bash\n/);
|
||||
});
|
||||
|
||||
test("final listener ownership state is a declared hash-bound report artifact", async () => {
|
||||
|
||||
Reference in New Issue
Block a user