Follow-up from #905 (PR #994), found by the cross-family review.
Problem
core/gates.py runs npm test, npm run build, npm run type-check, and the test_command/lint_command values from .codeframe/config.yaml — all repo-controlled strings — with the operator's full environment and real HOME.
A cloned repo committing this package.json:
{"scripts": {"test": "cat $HOME/.codeframe/credentials.encrypted"}}
is read by cf review or cf proof run. The credential store's Fernet key is machine-id-derived unless CODEFRAME_CREDENTIAL_SECRET is set, so this exfiltrates every provider key and the GitHub PAT.
Why it was not fixed in #905
#905 added core/agent_env.py:build_agent_env() and routed run_command, run_tests, and the legacy plan-engine shell through it. Applying it here is a one-line change per call site — but unlike those, gates run on a user-invoked command. A project whose test suite legitimately needs ~/.npmrc, ~/.aws, or a real ~/.cache would break. That trade-off deserves its own review rather than riding along in a security fix.
Suggested approach
- Route the gate subprocesses through
build_agent_env().
- Decide the escape hatch: likely an opt-out (
CODEFRAME_GATES_INHERIT_ENV=1) or reuse of the cf hooks trust decision, since test_command is repo-supplied in exactly the way hook commands are.
- Test: a repo whose
package.json test script reads $HOME records a sandboxed path, not the operator's.
Evidence
codeframe/core/gates.py:713, :918, :999
- Shared helper:
codeframe/core/agent_env.py
Follow-up from #905 (PR #994), found by the cross-family review.
Problem
core/gates.pyrunsnpm test,npm run build,npm run type-check, and thetest_command/lint_commandvalues from.codeframe/config.yaml— all repo-controlled strings — with the operator's full environment and realHOME.A cloned repo committing this
package.json:{"scripts": {"test": "cat $HOME/.codeframe/credentials.encrypted"}}is read by
cf revieworcf proof run. The credential store's Fernet key is machine-id-derived unlessCODEFRAME_CREDENTIAL_SECRETis set, so this exfiltrates every provider key and the GitHub PAT.Why it was not fixed in #905
#905 added
core/agent_env.py:build_agent_env()and routedrun_command,run_tests, and the legacy plan-engine shell through it. Applying it here is a one-line change per call site — but unlike those, gates run on a user-invoked command. A project whose test suite legitimately needs~/.npmrc,~/.aws, or a real~/.cachewould break. That trade-off deserves its own review rather than riding along in a security fix.Suggested approach
build_agent_env().CODEFRAME_GATES_INHERIT_ENV=1) or reuse of thecf hooks trustdecision, sincetest_commandis repo-supplied in exactly the way hook commands are.package.jsontest script reads$HOMErecords a sandboxed path, not the operator's.Evidence
codeframe/core/gates.py:713,:918,:999codeframe/core/agent_env.py