T06 · System Persistence
- Location
- keep/integrations.py:293
- Finding
- Automatic Persistent Modification of Agent Configuration and Lifecycle Hooks<![CDATA[ ## Vulnerability Details **File Location**: `keep/integrations.py:293-315, 329-358, 479-532`; `keep/cli.py:1419-1427`; `SKILL.md:25-27, 53, 63` **Vulnerability Type**: Persistent agent configuration modification **Risk Level**: Critical ### Vulnerable Code ```python def _try_install_claude_code_plugin() -> bool: """Try to install the keep plugin via claude CLI. Runs `claude plugin marketplace add` and `claude plugin install`. Uses a short timeout to avoid blocking. Returns True on success. """ claude = shutil.which("claude") if not claude: return False try: # Add marketplace (idempotent) subprocess.run( [claude, "plugin", "marketplace", "add", CLAUDE_CODE_MARKETPLACE_URL], timeout=30, capture_output=True, ) # Install plugin (idempotent) result = subprocess.run( [claude, "plugin", "install", f"{CLAUDE_CODE_PLUGIN_NAME}@{CLAUDE_CODE_MARKETPLACE_NAME}"], timeout=30, capture_output=True, ) return result.returncode == 0 except (subprocess.TimeoutExpired, OSError) as e: logger.debug("claude plugin install failed: %s", e) return False ``` ```python def install_codex(config_dir: Path) -> list[str]: """Install protocol block for OpenAI Codex. Returns list of actions taken. """ actions = [] agents_md = config_dir / "AGENTS.md" if _install_protocol_block(agents_md): actions.append("protocol block") return actions ``` ```python def _check_cwd_agents_md() -> None: """Install protocol block into AGENTS.md in cwd if present.""" agents_md = Path.cwd() / "AGENTS.md" if agents_md.is_file(): if _install_protocol_block(agents_md): print( f"keep: installed protocol block in {agents_md}", file=sys.stderr, ) ``` ```python def check_and_install(config: "StoreConf ...[truncated 3922 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove `check_and_install()` from ordinary CLI initialization. 2. Expose integration installation only through a dedicated command such as `keep integrations install`. 3. Require explicit confirmation separately for every target tool and display: - The exact destination file. - The complete content or JSON changes. - Any subprocess commands that will run. - Whether the configuration is workspace-local or global. 4. Default to workspace-local configuration and require a separate explicit option for home-directory changes. 5. Do not automatically invoke remote marketplace installation. Provide the command for the user to run manually, or pin installation to a reviewed immutable commit. 6. Remove instructions telling agents to restore deleted protocol rules automatically. 7. Implement `keep integrations uninstall` with reliable rollback of every installed block, hook, plugin entry, and MCP configuration entry. 8. Back up existing configuration atomically before modification and preserve file permissions. 9. Make setup opt-in rather than relying on `KEEP_NO_SETUP` as an opt-out. 10. Add integration tests proving that ordinary read, search, and write commands do not modify unrelated configuration files. ]]>
