MCP Plugin Persistence Registration
AI coding assistants like Claude, Cursor, and Codex use Model Context Protocol (MCP) configuration files to decide which external tools they can call. This rule flags commands that add or rewrite those config files, since doing so lets an attacker's tool get automatically reloaded every time the agent restarts, without needing to re-run any exploit.
How the attack works
An attacker (or malicious script) runs a command that touches a known MCP config file, such as claude_desktop_config.json, .mcp.json, cline_mcp_settings.json, .claude.json, ~/.codex/config.toml or ~/.gemini/settings.json. This can happen three ways: using the agent's own registration command (like `claude mcp add`), using a shell write tool (redirect, tee, sed -i, curl -o) that targets one of these files directly, or using a scripting language one-liner that opens and writes into the file. Once the entry is written, the agent will load that MCP server on every future session, giving the attacker a standing, in-band tool the agent will trust and invoke going forward. The rule ignores plain reads or diffs of these files, only firing when a write actually targets them.
Netzilo detection
Netzilo reports this behaviour when it is observed.
- Signature ID
- 7f3d9c21-6b4e-4a58-9c2f-1e0d5b8a3f47
- Severity
- High
Why it matters
A successful write gives an attacker a persistent foothold inside the AI agent's tool set — surviving restarts and session teardown — which can be used to run arbitrary tools with whatever privileges the agent has, without further exploitation.
What you can do
- →Review MCP config files (claude_desktop_config.json, .mcp.json, .claude.json, ~/.codex/config.toml, ~/.gemini/settings.json, etc.) regularly for unrecognized server entries.
- →Restrict who can run agent CLI commands (`mcp add`, `--add-mcp`) and script write access to these config paths, especially on shared or CI machines.
- →Treat dotfile managers and onboarding scripts that write these files as a known, allow-listed source, and flag any write to them from other processes.
- →Pin or version-control expected MCP server lists so unexpected additions are visible in diffs before the agent reloads them.
Known benign look-alikes
- Developer or IT onboarding script registering an approved MCP server via `claude mcp add` / `codex mcp add` / `code --add-mcp`
- Dotfile and configuration managers (chezmoi, GNU stow, Ansible, Nix home-manager, Puppet) templating claude_desktop_config.json or .mcp.json onto a workstation
- Devcontainer, Codespaces or CI postCreate scripts generating a repo-local .mcp.json for the project
- jq / sed based config migration during a legitimate MCP server version upgrade or import from Claude Desktop
- An editor extension rewriting its own MCP settings file when the user changes preferences in the UI