Skip to content

feat(ai_guard): detect project-scope MCP auto-execution (TrustFall) (#145)#153

Merged
Ju571nK merged 7 commits into
mainfrom
feat/trustfall-project-mcp-145
Jun 13, 2026
Merged

feat(ai_guard): detect project-scope MCP auto-execution (TrustFall) (#145)#153
Ju571nK merged 7 commits into
mainfrom
feat/trustfall-project-mcp-145

Conversation

@Ju571nK

@Ju571nK Ju571nK commented Jun 13, 2026

Copy link
Copy Markdown
Owner

Closes #145.

What

Detect the TrustFall class — a repository that commits a project MCP payload (<repo>/.mcp.json) together with settings keys that auto-launch it on folder-trust (a 1-click RCE on opening the repo). Detection/posture only — no enforce/deny (that is #100).

How

  • New reason AiGuardReason::ProjectMcpAutoEnabled { mechanism } (sigil-core), rubric weight 2.5 (project_mcp_auto_enabled). Solo → Medium; with a suspicious launcher → High; with destructive → Critical.
  • Claude project parser now reads <repo>/.mcp.json (mcpServers) and routes each server through the existing emit_one_server attack-shape scorer (ai-guard: score MCP stdio launchers by attack shape (shell / transient-path) above the benign baseline #127), deduplicated by name with settings mcpServers (settings precedence — a name in both scores once).
  • Auto-enable triggers = the two server-enable keys only: enableAllProjectMcpServers == true and a non-empty enabledMcpjsonServers. The project parser emits only when a key is present and .mcp.json actually ships servers. permissions.allow:["mcp__*"] is intentionally not a trigger (tool-call permission ≠ server pre-approval).
  • User-global blanket: a user-scope enableAllProjectMcpServers: true emits on the key alone (blanket pre-approval across every repo).
  • Cursor / Gemini use "Option B": amplify with ProjectMcpAutoEnabled{mechanism:"folder-trust autorun (default)"} only when the project config produced a local/risky MCP reason — benign remote-only configs do not amplify (no alert fatigue).
  • Antigravity deferred (its MCP lives in a global file, not per-repo) — documented, no behavior change.
  • ws:// / wss:// now classified as remote in emit_one_server.
  • Discovery + watch: a repo with only .mcp.json (no .claude/settings.json) is now discovered (new discover_claude_repos union helper, used at both boot and reload) and watched (.mcp.json added to the synthetic WatchTarget and to ClaudeCodeProjectParser::watched_paths()).

Hardening (post-review)

  • Defensive .mcp.json read: a malformed .mcp.json no longer aborts the whole assess and blind detection of a malicious .claude/settings.json in the same repo (corrupt-sidecar evasion seam). Degrades to "no payload"; settings-side reasons still score. Regression test added.

Tests

~16 new tests: payload scoring, the two auto-enable keys, the mcp__* negative guard, name dedup, user-global blanket, Option B local-vs-remote for Cursor/Gemini, ws remote, .mcp.json-only discovery, watched-paths, corrupt-sidecar resilience, rubric weight/bucket math. Full suite green; clippy -D warnings clean.

Out of scope (follow-ups)

🤖 Generated with Claude Code

@Ju571nK Ju571nK merged commit 9b35ef6 into main Jun 13, 2026
5 checks passed
@Ju571nK Ju571nK deleted the feat/trustfall-project-mcp-145 branch June 13, 2026 02:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Detect project-scope MCP auto-execution enablement (TrustFall / 1-click RCE class)

1 participant