feat(rules): persistence and supply chain detection#6
Open
MiguelHzBz wants to merge 2 commits intoleogr:mainfrom
Open
feat(rules): persistence and supply chain detection#6MiguelHzBz wants to merge 2 commits intoleogr:mainfrom
MiguelHzBz wants to merge 2 commits intoleogr:mainfrom
Conversation
Adds rules/default/persistence-detection.yaml with 6 rules covering extension vectors beyond MCP and skill files: - Deny hooks injection into Claude Code settings (CRITICAL): blocks writing a hooks block to settings.json — hooks run arbitrary commands before/after every tool call across all future sessions. - Ask before MCP registration in settings.json (WARNING): closes the alternative mcpServers registration path not covered by .mcp.json rules. - Ask before git hooks write (WARNING): .git/hooks/ files persist for the lifetime of the repo clone and execute outside the sandbox. - Ask before package registry redirect (WARNING): .npmrc/.pypirc/pip.conf redirects every subsequent install to an attacker-controlled index. - Deny API base URL override in env file (CRITICAL): ANTHROPIC_BASE_URL / OPENAI_BASE_URL override proxies all model traffic through an attacker endpoint where prompts and responses can be read or modified. - Ask before AI API key written to env file (WARNING): prevents accidental key commit to version control or staging for exfiltration. Includes test_persistence_rules.sh with 40 test cases (40/40 verified).
f0a8207 to
b979268
Compare
- Add .pnpmrc and .yarnrc.yml to is_registry_config_write (P3, P4) - Add npmRegistryServer to is_registry_redirect_content for yarn v2 (P4) - Add .env.staging, .env.test, .env.ci, .env.override to is_env_file_write (P5, P6) - Add Rule 7: Ask before Bash command accessing .git/hooks/ path (P1: shell redirection bypasses Write/Edit-only Rule 3) - Add Rule 8: Ask before Bash CLI registry redirect (npm config set, pip config set) (P2: CLI-level redirect never goes through Write/Edit tool path) - Add test_persistence_bypass.sh covering all 6 bypass sections (~20 test cases)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
rules/user/persistence-detection.yamlwith 6 rules covering extension vectors beyond MCP and skill files:hooksblock tosettings.json— hooks run arbitrary commands before/after every tool call across all future sessions, outside the sandboxmcpServerskey path insettings.jsonnot covered by.mcp.jsonrules.git/hooks/files persist for the lifetime of the repo clone and execute outside any sandbox on every git operation.npmrc/.pypirc/pip.confwith registry redirect sends every subsequent install to an attacker-controlled indexANTHROPIC_BASE_URL/OPENAI_BASE_URL/OPENAI_API_BASEin.envfiles proxies all model traffic through an attacker-controlled endpointTest plan
bash tests/test_persistence_rules.sh— 40 test cases (40/40 verified), including a cross-rule escalation test where a single.envwrite triggers both the deny rule (base URL override) and the ask rule (API key), with deny winning