cfgaudit

Rules / CFG127

CFG127 an MCP server runs a script from a hidden home directory

Severity: error · info OWASP: LLM04:2026 – Supply Chain OWASP Agentic: ASI04 – Agentic Supply Chain Vulnerabilities Agents: claude-code, claude-desktop, cline, codex, continue, copilot, cursor, devin, devin-desktop, gemini-cli, grok, kimi-code, opencode, qwen-code, roo-code, vscode, zed

What cfgaudit checks

CFG127 checks MCP entries when a language runtime (node, bun, deno, Python, or Ruby) starts a script below a hidden directory directly under a home directory, an OS temporary directory, or the cache directory under a home directory. These locations keep executable server code outside the project and ordinary package review.

An entry is error when MCP_SERVER_NAME matches the name of that hidden home directory. This is the strong correlation published for the SANDWORM_MODE npm campaign, which generated a developer-looking name, wrote server.js below ~/.<name>/, and registered that server in several assistants. A suspicious location without that correlation is info: developers sometimes run their own user-global server from a hidden directory, and cfgaudit does not yet have representative user-machine prevalence data.

Known agent, editor, and package-manager installation paths, ~/.config and ~/.local, package node_modules, and project-relative scripts are excluded, also when a project folder is called tmp or .cache. The strongly correlated campaign form is reported in every scope. The weaker info heuristic applies only to user-global files discovered with --user, avoiding reports on ordinary project configurations.

With --user, cfgaudit reads the campaign's JSON MCP targets for Claude Code, Claude Desktop on Linux/macOS/Windows, Cursor, Continue, and Windsurf. Continue's normal ~/.continue/config.yaml and Windsurf's older Codeium path remain supported too.

Trigger example

{
  "mcpServers": {
    "dev-utils": {
      "command": "node",
      "args": ["/home/user/.dev-utils/server.js"],
      "env": {"MCP_SERVER_NAME": "dev-utils"}
    }
  }
}

Safe alternative

Remove an entry you did not create and investigate both the referenced script and recently installed packages before deleting evidence. Rotate credentials if the server may have run. For a legitimate local server, keep reviewed source in a documented directory and point the MCP entry at a pinned package runner or a stable installation path.

cfgaudit performs static configuration analysis. It does not start or connect to the MCP server, inspect the tools it exposes at runtime, or trust their descriptions. A clean result therefore cannot establish that a running server is safe.

References

Documentation for cfgaudit 1.21.0. Source of this page · Rule implementation