Skip to content

fix(mcp): Claude can save files via CODEC (beat #18) + close ~/.ssh write hole#242

Merged
AVADSA25 merged 1 commit into
mainfrom
claude/mcp-file-write
Jul 13, 2026
Merged

fix(mcp): Claude can save files via CODEC (beat #18) + close ~/.ssh write hole#242
AVADSA25 merged 1 commit into
mainfrom
claude/mcp-file-write

Conversation

@AVADSA25

Copy link
Copy Markdown
Owner

Claude→CODEC→save-a-file got 'No approval received' — the MCP gate blanket-refused file_write despite it being purpose-built for remote callers. Now file_write (which self-guards) is allowed over MCP; delete/shell/messaging/browser stay refused. The end-to-end test surfaced a real hole — file_write could write to ~/.ssh/authorized_keys (SSH-key injection) because the blocklist only checked filenames; now the sensitive-dir subtrees + shell-init dotfiles are blocked. 55 tests, verified end to end.

…h write hole

Claude-in-Claude-Desktop told CODEC to save a file to ~/Downloads and got
"No approval received". Cause: the MCP consent gate BLANKET-refuses every
destructive skill (codec_consent), and file_write is classified destructive —
even though file_write was PURPOSE-BUILT for remote MCP callers (write-only,
path-safe, size-capped, audited). The refusal contradicted its own design.

- codec_consent.mcp_allowed(): a destructive skill may run over MCP only if it
  self-guards. _MCP_SELF_GUARDED = {file_write}. So Claude can save files;
  file_ops (delete/move), terminal, python_exec, imessage_send and pilot stay
  refused. codec_mcp.py uses mcp_allowed() instead of the blanket is_destructive.

- SECURITY (found by the end-to-end test before shipping): file_write happily
  wrote to ~/.ssh/evil. The blocklist only matched the *basename* for ".ssh", so
  a write INTO ~/.ssh (e.g. authorized_keys — SSH-key injection) or ~/.zshrc
  (code exec on next shell) slipped through. Now blocks the whole subtree of
  ~/.ssh ~/.aws ~/.gnupg ~/.kube ~/.gcloud ~/.docker ~/.azure ~/.config/gcloud
  ~/.config/gh ~/.password-store, plus shell-init dotfiles + authorized_keys +
  crontab by name. Especially important now file_write is reachable remotely.

Verified END TO END: a remote-style file_write to ~/Downloads succeeds; writes
to ~/.ssh/authorized_keys, ~/.aws/credentials, ~/.zshrc, ~/.gnupg/*, ~/.gcloud/*
are all refused. 55 tests pass (18 new incl. the sensitive-dir matrix). D-1
manifest regenerated. ruff clean.

Live-test (beat #18): in Claude Desktop with the CODEC connector, "use CODEC to
save this to my Downloads" now writes the file; "save to ~/.ssh/..." is refused.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@AVADSA25
AVADSA25 merged commit f446b70 into main Jul 13, 2026
1 check passed
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.

2 participants