--- title: "Security Hardening Guide" description: "Active threats, injection defense, and CVE-based security hardening for Claude Code" tags: [security, guide, hooks] keywords: - "hardening claude code" - "cve-2026-25725" - "circumventing security in claude code" --- # Security Hardening Guide > **Confidence**: Tier 2, based on CVE disclosures, security research (2024-2026), and community validation > > **Scope**: Active threats (attacks, injection, CVE). For data retention and privacy, see [data-privacy.md](./data-privacy.md) --- ## TL;DR - Decision Matrix | Your Situation | Immediate Action | Time | |----------------|------------------|------| | **Solo dev, public repos** | Install output scanner hook | 5 min | | **Team, sensitive codebase** | + MCP vetting + injection hooks | 30 min | | **Enterprise, production** | + ZDR + integrity verification | 2 hours | **Right now**: Check your MCPs against the [Safe List](#mcp-safe-list-community-vetted) below. > **NEVER**: Approve MCPs from unknown sources without version pinning. > **NEVER**: Run database MCPs on production without read-only credentials. --- ## Part 1: Prevention (Before You Start) ### 1.1 MCP Vetting Workflow Model Context Protocol (MCP) servers extend Claude Code's capabilities but introduce significant attack surface. Understanding the threat model is essential. **Command allowlist, not blanket auto-approval.** Granting an agent permission to run all commands eliminates approval friction but grants the agent host-user-level capability. A practical baseline: allow `git add` and `git commit`, but require explicit approval before `git push`, hard resets, force-deletes, or any database mutation. Jocelyn N'takpe (Head of Engineering & Architecture, ManoMano) documented losing all Firefox bookmarks to an agent that misidentified them as "context to clear" during a cleanup task, illustrating that the blast radius of broad permissions extends well beyond production systems. ([IFTTD ep 346 "IA & DevX"](https://www.ifttd.io/episodes/ia-devx)) --- #### Attack: MCP Rug Pull ``` ┌─────────────────────────────────────────────────────────────┐ │ 1. Attacker publishes benign MCP "code-formatter" │ │ ↓ │ │ 2. User adds to ~/.claude.json, approves once │ │ ↓ │ │ 3. MCP works normally for 2 weeks (builds trust) │ │ ↓ │ │ 4. Attacker pushes malicious update (no re-approval!) │ │ ↓ │ │ 5. MCP exfiltrates ~/.ssh/*, .env, credentials │ └─────────────────────────────────────────────────────────────┘ MITIGATION: Version pinning + hash verification + monitoring ``` This attack exploits the one-time approval model: once you approve an MCP, updates execute automatically without re-consent. #### CVE Summary (2025-2026) | CVE | Severity | Impact | Mitigation | |-----|----------|--------|------------| | **CVE-2025-53109/53110** | High | Filesystem MCP sandbox escape via prefix bypass + symlinks | Update to >= 0.6.3 / 2025.7.1 | | **CVE-2025-54135** | High (8.6) | RCE in Cursor via prompt injection rewriting mcp.json | File integrity monitoring hook | | **CVE-2025-54136** | High | Persistent team backdoor via post-approval config tampering | Git hooks + hash verification | | **CVE-2025-49596** | Critical (9.4) | RCE in MCP Inspector tool | Update to patched version | | **CVE-2026-24052** | High | SSRF via domain validation bypass in WebFetch | Update to v1.0.111+ | | **CVE-2025-66032** | High | 8 command execution bypasses via blocklist flaws | Update to v1.0.93+ | | **ADVISORY-CC-2026-001** | High | Sandbox bypass: commands excluded from sandboxing bypass Bash permissions (no CVE assigned) | **Update to v2.1.34+ immediately** | | **CVE-2026-0755** | **Critical (9.8)** | RCE in gemini-mcp-tool: LLM-generated args passed to shell without validation; no auth, network-reachable | **No fix yet**, avoid using in production or on exposed networks | | **SNYK-PYTHON-MCPRUNPYTHON-15250607** | High | SSRF in mcp-run-python: Deno sandbox permits localhost access, enabling internal network pivoting | Restrict sandbox network permissions; block localhost range | | **CVE-2026-25725** | High | Claude Code sandbox escape: malicious code inside bubblewrap sandbox creates missing `.claude/settings.json` with SessionStart hooks that execute with host privileges on restart | Update to >= v2.1.2 (covered by v2.1.34+) | | **CVE-2026-25253** | High (8.8) | OpenClaw 1-click RCE: malicious link triggers WebSocket to attacker-controlled server, exfiltrating auth token; 17,500+ exposed instances found | Update OpenClaw to >= 2026.1.29; block public internet exposure | | **CVE-2026-0757** | High | MCP Manager for Claude Desktop sandbox escape via command injection in execute-command with unsanitized MCP config objects | Restrict to trusted configs; check upstream for patch | | **CVE-2025-35028** | **Critical (9.1)** | HexStrike AI MCP Server: semicolon-prefixed arg causes OS command injection in EnhancedCommandExecutor, typically running as root; no auth required | **No fix yet**, avoid exposing to untrusted inputs/networks | | **CVE-2025-15061** | **Critical (9.8)** | Framelink Figma MCP Server: fetchWithRetry method executes attacker-controlled shell metacharacters; unauthenticated RCE | Update to latest patched version | | **CVE-2026-3484** | Medium (6.5) | nmap-mcp-server (PhialsBasement): command injection in `child_process.exec` Nmap CLI handler; remotely exploitable | Apply patch commit `30a6b9e` | | **CVE-2026-33032** | **Critical (9.8)** | nginx-ui MCPwn: missing `AuthRequired()` on `/mcp_message` endpoint allows unauthenticated full nginx takeover in 2 HTTP requests; actively exploited, 2,689+ exposed instances | **Update to nginx-ui >= v2.3.4 immediately** | | **ADVISORY-MCP-STDIO-2026-001** | Critical | OX Security: MCP STDIO interface lacks input validation across all SDK languages, which enables RCE in any MCP-integrated app that doesn't sanitize inputs; Anthropic considers this by design; 150M+ downloads affected | Sanitize all STDIO inputs; sandbox MCP services; see OX Security advisory | | **CVE-2026-25723** | High | Claude Code file-write sandbox bypass: piped sed/echo commands escaped project sandbox because command chaining wasn't validated | Update to v2.0.55+ | | **CVE-2026-33068** | High | Claude Code permission mode bypass: settings.json resolved before workspace trust dialog, allowing `bypassPermissions` to silently skip consent | Update to v2.1.53+ | | **ADVISORY-CC-2026-002** | Medium | Claude Code deny-rule bypass: all configured deny rules silently dropped when command exceeded 50 subcommands | **Update to v2.1.90+** | | **CVE-2026-50548/50549** | **Critical (9.8 each)** | Cursor "DuneSlide" agent terminal sandbox escape (working-directory restriction bypass plus a symlink file-write escape when path canonicalization fails), letting zero-click prompt injection overwrite the sandbox binary and reach OS-level RCE | Update to Cursor Desktop 3.0+ | | **CVE-2026-12958/12957** | High (7.8) | "GhostApproval": a booby-trapped repo ships a file that is really a symlink to a sensitive path (`~/.ssh/authorized_keys`, agent config), so the agent writes attacker content there while the approval dialog shows a benign in-project path. Class flaw across Amazon Q, Cursor, Claude Code, Antigravity, Augment, Windsurf | Amazon Q language server >= 1.69.0; Cursor >= 3.0; never approve writes to symlinked paths. Anthropic disputes it applies to Claude Code (folder-trust equals consent) | | **CVE-2026-59950** | High | MCP Python SDK's deprecated WebSocket server transport skips Host/Origin validation on the handshake, so a hostile web page can drive a user's local MCP server via a cross-site WebSocket connection (auth bypass) | Update `mcp` (PyPI) to >= 1.28.1; stop using the deprecated `websocket_server` transport | | **CVE-2026-48124** | High | Cursor: a workspace-controlled `.claude`/`.cursor` hook config is trusted and run outside the agent sandbox on next launch, one instance of a broader "configuration-based sandbox escape" pattern also seen in Codex CLI, Gemini CLI, and Antigravity | Update Cursor to >= 3.0.0; treat repo-provided hook/config files as untrusted until reviewed | | **CVE-2026-54316** | **Critical (9.1 NVD)** | Claude Code: `huggingface.co` was allowlisted as a *bare hostname* for WebFetch, so any path on it was fetched with no prompt. Researchers created 64 model repos, one per possible character, and read an API key back one character at a time off Hugging Face's public download counter. Exfiltration over a domain the operator trusted on purpose. Affects 0.2.54 through 2.1.162 | **Update to >= 2.1.163.** Then audit your own allowlists: never allowlist a bare hostname on a domain where third parties can create content and read a public metric. Anthropic self-scored this 6.0 (v4) against NVD's 9.1 | | **CVE-2026-12537** | **Critical (10.0 CVSS v4)** | Gemini CLI + `run-gemini-cli` GitHub Action: headless CI trusts the workspace automatically, so a `.gemini/.env` shipped in an untrusted PR loads as config and runs OS commands on the CI host **before the sandbox initialises**. A chained flaw read a sibling process's environment via `/proc/[PID]/environ` and pushed a backdoored commit | Update Gemini CLI to >= 0.39.1 **and** the Action to >= 0.1.22 (patching one leaves the path open); disable automatic workspace trust for untrusted PRs | | **CVE-2026-67431** | **Critical (9.1 NVD / 8.3 v4)** | MCP Ruby SDK: session IDs are not bound to a session owner, so a stolen ID lets an attacker run `tools/call` inside the victim's session with responses delivered to the victim's own SSE stream. Silent by design | Update the `mcp` gem to >= 0.23.0. Four sibling advisories ship in the same release: CVE-2026-67432 (unbounded request body read *before* auth), CVE-2026-63118 (no Host/Origin check, DNS rebinding), CVE-2026-63119 (unbounded stdio line reads), CVE-2026-67430 (sessions never expire) | **v2.1.90 Security Fix (May 2026)**: Claude Code v2.1.90 patched the 50-subcommand deny-rule bypass (ADVISORY-CC-2026-002) where all configured deny rules were silently dropped when a command chain exceeded 50 subcommands. **Upgrade immediately** if running v2.1.89 or earlier. **v2.1.34 Security Fix (Feb 2026)**: Claude Code v2.1.34 patched a sandbox bypass vulnerability where commands excluded from sandboxing could bypass Bash permission enforcement. **Upgrade immediately** if running v2.1.33 or earlier. Note: this is separate from CVE-2026-25725 (a different sandbox escape fixed later). **⚠️ CVE-2026-0755 (Feb 2026, No Patch)**: Critical RCE in `gemini-mcp-tool` (CVSS 9.8). An attacker can send crafted JSON-RPC `CallTool` requests with malicious arguments that execute arbitrary code on the host machine with full service account privileges. No fix confirmed as of 2026-02-22. Do not expose gemini-mcp-tool to untrusted networks. **⚠️ CVE-2025-35028 (No Patch)**: Critical RCE in HexStrike AI MCP Server (CVSS 9.1). Passing any argument starting with `;` to the API endpoint executes arbitrary OS commands, typically as root. No fix confirmed. Do not expose this server to untrusted inputs or networks. **⚠️ CVE-2025-15061 (Jan 2026)**: Critical RCE in Framelink Figma MCP Server (CVSS 9.8). The `fetchWithRetry` method passes unsanitized user input to shell: unauthenticated remote code execution. Update Figma MCP Server to the latest patched version immediately. **⚠️ CVE-2026-33032 (MCPwn, April 2026, Actively Exploited)**: Critical authentication bypass in nginx-ui's MCP integration (CVSS 9.8). The `/mcp_message` endpoint is missing the `AuthRequired()` middleware, allowing any network-adjacent attacker to invoke 12 destructive MCP tools, including nginx config write/reload, with zero authentication in two HTTP requests. Added to VulnCheck KEV April 13, 2026. 2,689+ publicly reachable instances confirmed. **Update nginx-ui to >= v2.3.4 immediately.** Chains with CVE-2026-27944 (unauthenticated `/api/backup` endpoint leaking SSL keys and credentials). **⚠️ CVE-2026-25253 (OpenClaw, Feb 2026)**: One-click RCE affecting OpenClaw/clawdbot/Moltbot (CVSS 8.8). A malicious link causes OpenClaw to automatically establish a WebSocket to an attacker-controlled server, leaking the auth token, which grants full system control since OpenClaw runs with filesystem and shell access. Over 17,500 internet-exposed instances identified. Update to >= 2026.1.29. **Source**: [Cymulate EscapeRoute](https://cymulate.com/blog/cve-2025-53109-53110-escaperoute-anthropic/), [Checkpoint MCPoison](https://research.checkpoint.com/2025/cursor-vulnerability-mcpoison/), [Cato CurXecute](https://www.catonetworks.com/blog/curxecute-rce/), [SentinelOne CVE-2026-24052](https://www.sentinelone.com/vulnerability-database/cve-2026-24052/), [Flatt Security](https://flatt.tech/research/posts/pwning-claude-code-in-8-different-ways/), [Penligent AI CVE-2026-0755](https://www.penligent.ai/hackinglabs/de/deep-analysis-of-gemini-mcp-tool-command-injection-cve-2026-0755-when-an-mcp-toolchain-hands-user-input-to-the-shell/), Claude Code CHANGELOG #### Attack Patterns | Pattern | Description | Detection | |---------|-------------|-----------| | **Tool Poisoning** | Malicious instructions in tool metadata (descriptions, schemas) influence LLM before execution | Schema diff monitoring | | **Rug Pull** | Benign server turns malicious after gaining trust | Version pinning + hash verify | | **Confused Deputy** | Attacker registers tool with trusted name on untrusted server | Namespace verification | #### 5-Minute MCP Audit Before adding any MCP server, complete this checklist: | Step | Command/Action | Pass Criteria | |------|----------------|---------------| | **1. Source** | `gh repo view ` | Stars >50, commits <30 days | | **2. Permissions** | Review `mcp.json` config | No `--dangerous-*` flags | | **3. Version** | Check version string | Pinned (not "latest" or "main") | | **4. Hash** | `sha256sum ` | Matches release checksum | | **5. Audit** | Review recent commits | No suspicious changes | #### MCP Safe List (Community Vetted) | MCP Server | Status | Notes | |------------|--------|-------| | `@anthropic/mcp-server-*` | Safe | Official Anthropic servers | | `context7` | Safe | Read-only documentation lookup | | `sequential-thinking` | Safe | No external access, local reasoning | | `memory` | Safe | Local file-based persistence | | `filesystem` (unrestricted) | Risk | CVE-2025-53109/53110 - use with caution | | `database` (prod credentials) | Unsafe | Exfiltration risk - use read-only | | `browser` (full access) | Risk | Can navigate to malicious sites | | `mcp-scan` (Snyk) | Tool | Supply chain scanning for skills/MCPs | *Last updated: 2026-02-11. [Report new assessments](https://github.com/FlorianBruniaux/claude-code-ultimate-guide/issues)* #### Secure MCP Configuration Example ```json { "mcpServers": { "context7": { "command": "npx", "args": ["-y", "@context7/mcp-server@1.2.3"], "env": {} }, "database": { "command": "npx", "args": ["-y", "@company/db-mcp@2.0.1"], "env": { "DB_HOST": "readonly-replica.internal", "DB_USER": "readonly_user" } } } } ``` **Key practices**: - Pin exact versions (`@1.2.3`, not `@latest`) - Use read-only database credentials - Minimize environment variables exposed ### 1.2 Agent Skills Supply Chain Risks Third-party Agent Skills (installed via `npx add-skill` or plugin marketplaces) introduce supply chain risks similar to npm packages. **Snyk ToxicSkills** (Feb 2026) scanned **3,984 skills** across ClawHub and skills.sh: | Finding | Stat | Impact | |---------|------|--------| | Skills with security flaws | **36.82%** (1,467/3,984) | Over 1 in 3 skills is compromised | | Critical risk skills | **534** (13.4%) | Malware, prompt injection, exposed secrets | | Malicious payloads identified | **76** | Credential theft, backdoors, data exfiltration | | Hardcoded secrets (ClawHub) | **10.9%** | API keys, tokens exposed in skill code | | Remote prompt execution | **2.9%** | Skills fetch and execute distant content dynamically | Earlier research by [SafeDep](https://safedep.io/agent-skills-threat-model) estimated 8-14% vulnerability rate on a smaller sample. **Source**: [Snyk ToxicSkills](https://snyk.io/fr/blog/toxicskills-malicious-ai-agent-skills-clawhub/) **Mitigations**: - **Scan before installing**: `mcp-scan` (Snyk, open-source) achieves 90-100% recall on confirmed malicious skills with 0% false positives on top-100 legitimate skills - **Review SKILL.md before installing**: Check `allowed-tools` for unexpected access (especially `Bash`) - **Validate with skills-ref**: `skills-ref validate ./skill-dir` checks spec compliance ([agentskills.io](https://agentskills.io)) - **Pin skill versions**: Use specific commit hashes when installing from GitHub - **Audit scripts/**: Executable scripts bundled with skills are the highest-risk component **Test prompt injection systematically before shipping an agent to production.** A practical baseline covers at least five categories: system message manipulation, structured-output attacks, role-play framing designed to talk the model out of a refusal, and multi-turn manipulation that builds trust across several exchanges before the payload lands. The same scrutiny applies to third-party skills and agent definition files: installing one from the internet without reading its contents first is a direct injection vector, no different in kind from running an unaudited npm package. *Brian Vermeer, Devoxx, 2026* ```bash # Scan a skill directory with mcp-scan (Snyk) npx mcp-scan ./skill-directory # Validate spec compliance with skills-ref skills-ref validate ./skill-directory ``` #### The Delayed Payload: Why "Review SKILL.md" Is Not Enough Two of the mitigations above failed in the largest agent-skill campaign measured so far, and the way they failed is worth understanding before you rely on them. [Zenity Labs](https://labs.zenity.io/post/attackers-target-agents-via-the-skill-supply-chain) disclosed the campaign at Black Hat USA on 2026-08-06. Attackers cloned the legitimate Paperclip and Browser Use skills verbatim, published the copies under typosquatted names on skills.sh, and left them clean. The clones passed the marketplace checks precisely because they were byte-identical to skills that deserved to pass. They accumulated real installs and real trending position for weeks. On 2026-07-11 the operators pushed an update. By 2026-08-02 the family had crossed 1.7 million aggregate installs, a figure Zenity is careful to note is not user-unique. Reviewing `SKILL.md` would not have caught it. The malicious instructions lived in a secondary `setup-installation.md`, loaded only when the agent progressed to installing or starting the tool. That is progressive disclosure working exactly as designed, used as a hiding place. A mutable tag, slug, or marketplace reference would not have protected an earlier clean install from a later poisoned update. An immutable commit or digest pin would have held the reviewed content in place, but it still requires a fresh review before any update. The payload itself was never in the skill. The instructions told the agent to skip `npm` and `npx` and fetch a binary straight from an attacker-controlled GitHub release, which loaded a credential stealer that swept 138 distinct paths for SSH keys, cloud credentials, Kubernetes and Docker config, package-manager tokens, Terraform state, `.env` files and service-account files for Vercel, Netlify, Cloudflare, Firebase and Supabase. Zenity's wider registry sweep found that over 30% of dangerous skills use the agent this way, as the dropper rather than the payload. Three practices follow, and they are additive to the list above rather than replacing it: - **Scan the whole skill directory, not the entry file.** Follow every reference the way the agent would, including files it only reads at a later step. - **Pin immutable content, not a mutable name.** Use a commit hash or digest after review, then repeat the review before changing that pin. - **Re-review on every version bump with the same scrutiny as a first install.** Reputation is earned before the payload arrives. A clean history is what the attack is built on. - **Prefer dynamic analysis for anything that fetches at runtime.** Static review cannot evaluate a payload that does not exist yet at scan time. [AI Total](https://zenity.io/research/ai-total) (Zenity, free) detonates a skill in a live agent sandbox seeded with bait credentials and reports what it actually did. SkillDetonate takes the same approach at roughly 2.5 minutes per check. The IOCs, affected package versions and full remediation order are in `examples/commands/resources/threat-db.yaml` under the campaign `skills.sh Skill Supply Chain (Paperclip / Browser Use Typosquats)`. ### 1.3 Known Limitations of permissions.deny The `permissions.deny` setting in `.claude/settings.json` is the official method to block Claude from accessing sensitive files. However, security researchers have documented architectural limitations. #### What permissions.deny Blocks | Operation | Blocked? | Notes | |-----------|----------|-------| | `Read()` tool calls | ✅ Yes | Primary blocking mechanism | | `Edit()` tool calls | ✅ Yes | With explicit deny rule | | `Write()` tool calls | ✅ Yes | With explicit deny rule | | `Bash(cat .env)` | ✅ Yes | With explicit deny rule | | `Glob()` patterns | ✅ Yes | Handled by Read rules | | `ls .env*` (filenames) | ⚠️ Partial | Exposes file existence, not contents | #### Known Security Gaps | Gap | Description | Source | |-----|-------------|--------| | **System reminders** | Background indexing may expose file contents via internal "system reminder" mechanism before tool permission checks | [GitHub #4160](https://github.com/anthropics/claude-code/issues/4160) | | **Bash wildcards** | Generic bash commands without explicit deny rules may access files | Security research | | **Indexing timing** | File watching operates at a layer below tool permissions | [GitHub #4160](https://github.com/anthropics/claude-code/issues/4160) | #### Recommended Configuration Block **all** access vectors, not just `Read`: ```json { "permissions": { "deny": [ "Read(./.env*)", "Edit(./.env*)", "Write(./.env*)", "Bash(cat .env*)", "Bash(head .env*)", "Bash(tail .env*)", "Bash(grep .env*)", "Read(./secrets/**)", "Read(./**/*.pem)", "Read(./**/*.key)" ] } } ``` #### Defense-in-Depth Strategy Because `permissions.deny` alone cannot guarantee complete protection: 1. **Store secrets outside project directories**: Use `~/.secrets/` or external vault 2. **Use external secrets management**: AWS Secrets Manager, 1Password, HashiCorp Vault 3. **Add PreToolUse hooks**: Secondary blocking layer (see [Section 2.3](#23-hook-stack-setup)) 4. **Never commit secrets**: Even "blocked" files can leak through other vectors 5. **Review bash commands**: Manually inspect before approving execution > **Bottom line**: `permissions.deny` is necessary but not sufficient. Treat it as one layer in a defense-in-depth strategy. #### Built-in Permission Safeguards Beyond explicit deny rules, Claude Code has several built-in protections: | Safeguard | Behavior | |-----------|----------| | **Network allowlist** | No domain is pre-allowed. `curl` and `wget` are not blocklisted; they reach only the hosts in `sandbox.network.allowedDomains`, and a missing host hangs until timeout rather than failing cleanly | | **Fail-closed matching** | Any permission rule that doesn't match defaults to requiring manual approval (deny by default) | | **Command injection detection** | Suspicious bash commands require manual approval even if previously allowlisted | These protections work automatically without configuration. The fail-closed design means a misconfigured permission rule fails safe rather than granting unintended access. ### 1.4 Repository Pre-Scan Before opening untrusted repositories, scan for injection vectors: **High-risk files to inspect**: - `README.md`, `SECURITY.md`: Hidden HTML comments with instructions - `package.json`, `pyproject.toml`: Malicious scripts in hooks - `.cursor/`, `.claude/`: Tampered configuration files - `CONTRIBUTING.md`: Social engineering instructions **Quick scan command**: ```bash # Check for hidden instructions in markdown grep -r " commit + checkpoint | v [Policy Check] "Does this touch prisma/schema.prisma?" "Does this touch src/server/auth*?" | +----+----+ | | Low risk High risk | | Auto-OK Approval Gate "Reviewer inspects: transcript + diffs + attribution %" | Approve / Reject (immutable audit trail entry) ``` **Example compliance workflow:** ```bash # 1. Initialize with compliance mode entire init --compliance-mode="hipaa" # Sets: retention policy, encryption at rest, access controls # 2. Capture session with required metadata entire capture \ --agent="claude-code" \ --user="john.doe@company.com" \ --task="patient-data-encryption" \ --require-approval="security-officer" # 3. Work normally in Claude Code claude You: Implement AES-256 encryption for patient records [... Claude proposes implementation ...] # 4. Checkpoint requires approval (automatic gate) entire checkpoint --name="encryption-implemented" # Creates approval request, blocks further action until approved # 5. Security officer reviews entire review --checkpoint="encryption-implemented" # Shows: prompts, reasoning, diffs, test results, security implications # 6. Approve or reject entire approve \ --checkpoint="encryption-implemented" \ --approver="jane.smith@company.com" # Or: entire reject --reason="needs stronger key derivation" # 7. Export audit trail for compliance reporting entire audit-export --format="json" --since="2026-01-01" # Produces compliance-ready report with full provenance chain ``` **Compliance features:** | Feature | HIPAA | SOC2 | FedRAMP | Notes | |---------|-------|------|---------|-------| | **Audit logs** | ✅ | ✅ | ✅ | Prompts → reasoning → outputs | | **Approval gates** | ✅ | ✅ | ✅ | Human-in-loop before sensitive actions | | **Encryption at rest** | ✅ | ✅ | ✅ | AES-256 for session data | | **Access controls** | ✅ | ✅ | ⚠️ | Role-based (manual config) | | **Retention policies** | ✅ | ✅ | ✅ | Configurable per compliance framework | | **Provenance tracking** | ✅ | ✅ | ✅ | Full chain: user → prompt → AI → code | **Integration with existing security:** ```bash # Hook approval gates into CI/CD # .claude/hooks/post-commit.sh #!/bin/bash if [[ "$CLAUDE_SESSION_COMPLIANCE" == "true" ]]; then entire checkpoint --auto --require-approval="$APPROVAL_ROLE" fi ``` **When to use Entire CLI for compliance:** - ✅ SOC2, HIPAA, FedRAMP certification required - ✅ Need full AI decision provenance (prompts + reasoning + outputs) - ✅ Multi-agent workflows with handoff tracking - ✅ Approval gates before production deployments - ❌ Personal projects (overhead not justified) - ❌ Non-regulated industries (simple `Co-Authored-By` suffices) **Status:** Production v1.0+, SOC2 Type II certified (Entire CLI platform) > **Full docs**: [AI Traceability Guide](../ops/ai-traceability.md#51-entire-cli), [Third-Party Tools](../ecosystem/third-party-tools.md) ### 3.5 AI Kill Switch & Containment Architecture > **Context**: Agentic coding tools operate at the developer's privilege level: anything you can do, the agent can do ([Fortune, Dec 2025](https://fortune.com/2025/12/15/ai-coding-tools-security-exploit-software/)). No model provider has fully solved prompt injection. Plan your containment accordingly. **Three-level kill switch mapped to Claude Code:** | Level | Concept | Claude Code Mechanism | When to Use | |-------|---------|----------------------|-------------| | **1. Scoped Revocation** | Disable specific capabilities | [`dangerous-actions-blocker.sh`](../../examples/hooks/bash/dangerous-actions-blocker.sh) hook, `permissions.deny` in settings | Suspicious behavior, restrict scope | | **2. Velocity Governor** | Rate-limit or threshold triggers | Custom hook tracking command frequency, `--allowedTools` flag to restrict tool set | Agent acting erratically, too many changes | | **3. Global Hard Stop** | Kill everything immediately | `Ctrl+C` / `Esc`, `claude config set --disable`, uninstall | Confirmed compromise, emergency | **Practical example: Level 2 velocity governor hook** ```bash #!/bin/bash # .claude/hooks/velocity-governor.sh # Event: PreToolUse # Blocks if >20 Bash commands in 5 minutes (adjust thresholds) COUNTER_FILE="/tmp/claude-cmd-counter-$$" WINDOW=300 # 5 minutes THRESHOLD=20 # Count recent invocations NOW=$(date +%s) echo "$NOW" >> "$COUNTER_FILE" # Clean entries older than window if [[ -f "$COUNTER_FILE" ]]; then CUTOFF=$((NOW - WINDOW)) awk -v cutoff="$CUTOFF" '$1 >= cutoff' "$COUNTER_FILE" > "${COUNTER_FILE}.tmp" mv "${COUNTER_FILE}.tmp" "$COUNTER_FILE" COUNT=$(wc -l < "$COUNTER_FILE") if (( COUNT > THRESHOLD )); then echo '{"decision": "block", "reason": "Rate limit: >'"$THRESHOLD"' commands in '"$((WINDOW/60))"'min. Possible runaway agent."}' exit 0 fi fi exit 0 ``` **Regulatory context:** - **EU AI Act** (Aug 2025): Kill switches mandatory for high-risk AI systems. Non-compliance = fines up to 7% global turnover. If your org deploys Claude Code in regulated workflows, document your containment architecture. - **CoSAI AI Incident Response Framework V1.0** (Nov 2025): First framework addressing AI-specific incidents (data poisoning, prompt injection, model theft). Reference for teams building incident response procedures. ([OASIS](https://www.oasis-open.org/2025/11/18/coalition-for-secure-ai-releases-two-actionable-frameworks-for-ai-model-signing-and-incident-response/)) - **Governance-containment gap**: Industry data shows ~59% of orgs monitor AI agents, but only ~38% have actual kill-switch capability ([CDOTrends, Jan 2026](https://www.cdotrends.com/story/4854/your-fsi-ai-needs-kill-switch-should-terrify-you)). Monitoring without intervention = awareness without safety. --- ## Appendix: Quick Reference ### Security Posture Levels | Level | Measures | Time | For | |-------|----------|------|-----| | **Basic** | Output scanner + dangerous blocker | 5 min | Solo dev, experiments | | **Standard** | + Injection hooks + MCP vetting | 30 min | Teams, sensitive code | | **Hardened** | + Integrity verification + ZDR | 2 hours | Enterprise, production | ### Command Quick Reference ```bash # Scan for secrets gitleaks detect --source . --verbose # Check MCP config cat ~/.claude.json | jq '.mcpServers | keys' # Verify hook installation ls -la ~/.claude/hooks/ # Test Unicode detection echo -e "test\u200Bhidden" | grep -P '[\x{200B}-\x{200D}]' ``` --- ## Part 4: Integration (In Your Daily Workflow) ### 4.1 PR Security Review Workflow The most high-ROI use of Claude Code for security: systematic review of every PR before merge. Takes 2-3 minutes, catches issues before they reach production. #### Setup: Add to your PR checklist ```bash # Run from repo root before merging any PR git diff main...HEAD > /tmp/pr-diff.txt ``` Then in Claude Code: ``` Review the security implications of this PR diff. Focus: injection, auth bypass, secrets exposure, insecure deserialization. File: /tmp/pr-diff.txt Use the security-auditor agent for the analysis. ``` #### The 3-agent PR security pipeline For high-stakes PRs (auth changes, payment flows, data access), run in sequence: ``` Step 1 — Threat surface scan: "Use the security-auditor agent to analyze all changed files in this diff. Report CRITICAL and HIGH findings only. No fixes." Step 2 — Data flow trace: "For each CRITICAL finding from the audit, trace the full data flow: where does user input enter? where does it reach? what sanitization exists?" Step 3 — Patch (if findings): "Use the security-patcher agent with the findings report above. Propose patches for CRITICAL findings only. Do not apply without my review." ``` #### What to always check in a security PR review | Change type | Risk | What to look for | |-------------|------|-----------------| | New API endpoint | High | Auth check, input validation, rate limiting | | DB query change | High | Parameterized queries, index exposure | | Auth logic | Critical | Token validation, session management, privilege escalation | | File upload | High | MIME type, size limit, path traversal | | Third-party lib added | Medium | CVE check (`npm audit`, `cargo audit`) | | Env var added | Medium | Not hardcoded, in `.gitignore`, in `.env.example` | #### Integration with git hooks Automate the trigger in `.git/hooks/pre-push`: ```bash #!/bin/bash # Pre-push: remind to run security review for auth/payment changes CHANGED=$(git diff origin/main...HEAD --name-only) if echo "$CHANGED" | grep -qE "(auth|payment|token|session|password|crypt)"; then echo "⚠️ Security-sensitive files changed. Run /security-audit before pushing." echo " Files: $(echo "$CHANGED" | grep -E '(auth|payment|token|session)')" # Warning only — does not block push fi exit 0 ``` --- ## Claude Code as Security Scanner (Research Preview) Beyond securing Claude Code itself, Anthropic offers a dedicated vulnerability scanning feature: **Claude Code Security**. > ⚠️ **Research preview**: Access via waitlist only. Not yet in GA. Details: [claude.com/solutions/claude-code-security](https://claude.com/solutions/claude-code-security) ### What it does - Scans your entire codebase for vulnerabilities using contextual reasoning (traces data flows cross-files) - **Adversarial validation**: findings are challenged internally before surfacing to reduce false positives - Generates patch suggestions that preserve code structure and style - Requires human review and approval before any fix is applied ### How it differs from the Security Auditor Agent | | Security Auditor Agent (today) | Claude Code Security (preview) | |---|---|---| | **Access** | Available now, any plan | Waitlist only | | **Scope** | OWASP Top 10, rule-based | Whole codebase, semantic analysis | | **Patches** | No (reports only) | Yes (with human approval) | | **Model** | Configurable | Anthropic's most capable models | ### When to use which - **Now** → Use the [Security Auditor Agent](../../examples/agents/security-auditor.md) + [Security Patcher Agent](../../examples/agents/security-patcher.md) for full detect-then-patch coverage - **Now** → Use the [Security Gate Hook](../../examples/hooks/bash/security-gate.sh) to block vulnerable patterns at write time - **Waitlist** → Join the preview for deeper semantic analysis once your team needs it --- ## See Also - [Enterprise AI Governance](./enterprise-governance.md): Org-level MCP governance (approval workflow, registry, guardrail tiers). This guide covers individual MCP vetting; that guide covers org-level policy. - [Data Privacy Guide](./data-privacy.md): Retention policies, compliance, what data leaves your machine - [AI Traceability](../ops/ai-traceability.md): PromptPwnd vulnerability, CI/CD security, attribution policies - [Security Checklist Skill](../../examples/skills/security-checklist.md): OWASP Top 10 patterns for code review - [Security Auditor Agent](../../examples/agents/security-auditor.md): Automated vulnerability detection (read-only) - [Security Patcher Agent](../../examples/agents/security-patcher.md): Applies patches from audit findings (human approval required) - [Security Gate Hook](../../examples/hooks/bash/security-gate.sh): Blocks vulnerable code patterns at write time (7 patterns) - [MCP Registry Template](../../examples/scripts/mcp-registry-template.yaml): YAML format for tracking approved MCPs at org level - [Ultimate Guide §7.4](#74-security-hooks): Hook system basics - [Ultimate Guide §8.6](#86-mcp-security): MCP security overview - [Cross-Session Messaging](../workflows/cross-session-messaging.md): full `ListAgents`/`SendMessage` mechanics between independent sessions ## References - **CVE-2025-53109/53110** (EscapeRoute): [Cymulate Blog](https://cymulate.com/blog/cve-2025-53109-53110-escaperoute-anthropic/) - **CVE-2025-54135** (CurXecute): [Cato Networks](https://www.catonetworks.com/blog/curxecute-rce/) - **CVE-2025-54136** (MCPoison): [Checkpoint Research](https://research.checkpoint.com/2025/cursor-vulnerability-mcpoison/) - **CVE-2026-24052** (SSRF): [SentinelOne](https://sentinelone.com/vulnerability-database/) - **CVE-2025-66032** (Blocklist Bypasses): [Flatt Security](https://flatt.tech/research/posts/) - **Snyk ToxicSkills** (Supply Chain Audit): [snyk.io/blog/toxicskills](https://snyk.io/fr/blog/toxicskills-malicious-ai-agent-skills-clawhub/) - **mcp-scan** (Snyk): [github.com/snyk/mcp-scan](https://github.com/snyk/mcp-scan) - **GitGuardian State of Secrets 2025**: [gitguardian.com](https://www.gitguardian.com/state-of-secrets-sprawl-report-2025) - **Prompt Injection Research**: [Arxiv 2509.22040](https://arxiv.org/abs/2509.22040) - **MCP Security Best Practices**: [modelcontextprotocol.io](https://modelcontextprotocol.io/specification/draft/basic/security_best_practices) --- ## Part 7: Remote Control Security {#remote-control-security} > **Feature context**: Remote Control (Research Preview, Feb 2026) allows controlling a local Claude Code session from a phone, tablet, or browser. Available on Pro and Max plans only. ### Architecture ``` Local terminal ──HTTPS outbound──► Anthropic relay ──► Mobile/Browser (execution) (relay only) (control UI) ``` **Security properties:** - Zero inbound ports (reduces attack surface vs SSH tunnels or ngrok) - HTTPS only (encrypted in transit) - Multiple short-lived, narrowly scoped credentials (each limited to a specific purpose, expiring independently) - Execution stays 100% local ### Threat Model | Threat | Risk | Mitigation | |--------|------|------------| | **Session URL leak** | Full terminal access for whoever holds the URL | Treat URL as password: don't share in Slack/logs/screenshots | | **RCE via remote commands** | Attacker who gets the URL can run commands if they approve tool calls | Per-command approval prompts on mobile (not foolproof against active attacker) | | **Corporate policy violation** | Personal Claude account on corporate machine routes traffic through Anthropic relay | Verify policy before enabling, even on personal plans | | **Persistent session exposure** | Long-running sessions increase window of exposure | Close sessions when done; ~10min auto-timeout on disconnect | | **Shared/untrusted workstation** | Session URL valid while session is open | Never run remote-control on shared machines | > **Community perspective**: Senior devs immediately noted: "C'est une sacrée RCE qu'ils introduisent là." The session URL is effectively a live key to an executing terminal. The per-command approval mechanism limits accidental execution but does not protect against a determined attacker who holds the URL and approves all prompts. ### Best Practices ```bash # 1. Don't auto-enable — activate only when needed # Avoid: /config → auto-enable remote-control # 2. Use on a dedicated, hardened workstation # Not on machines with access to production credentials or secrets # 3. Close the session when done # Ctrl+C on local terminal, or dismiss from the mobile app # 4. Never share session URLs in team chats, tickets, or logs # They are live access tokens while the session is active # 5. Prefer use on personal dev machines # Not on corporate machines with elevated privileges ``` ### Enterprise Considerations Remote Control is **not available** on Team or Enterprise plans. However: - Developers on personal Pro/Max accounts may use it on corporate hardware - The relay traffic (your commands and Claude's responses) passes through Anthropic infrastructure - If your organization has strict data residency requirements, treat Remote Control like any cloud-routed tool - Recommended: use only on a dedicated "sandbox" workstation without access to production systems ### Comparison: Remote Control vs Alternatives | Method | Inbound ports | Data path | Risk level | |--------|---------------|-----------|------------| | **Remote Control** | None (outbound HTTPS) | Anthropic relay | Low-Medium | | **SSH + mobile terminal** | Yes (port 22) | Direct | Medium | | **ngrok tunnel** | None (outbound) | ngrok relay | Medium | | **VPN + SSH** | Yes (behind VPN) | VPN + direct | Low | For the highest security: prefer SSH over VPN rather than Remote Control, especially on sensitive environments. --- ## Part 8: Cross-Session Messaging Threat Model {#cross-session-messaging-threat-model} > **Feature context**: since v2.1.224, any two Claude Code sessions can message each other via `ListAgents` and `SendMessage`, on the same machine automatically, or across your account through Remote Control. Full mechanics: [Cross-Session Messaging](../workflows/cross-session-messaging.md). ### Architecture ``` Same machine: Session A ──Unix socket / named pipe──► Session B (never touches Anthropic servers) Other machine: Session A ──HTTPS──► Anthropic relay ──► Remote Control ──► Session B Web session: Session A ──HTTPS──► Anthropic relay ──► Session B (Claude Code on the web) ``` Each session registers itself in on-disk files and binds an inbox socket restricted to the operating-system user (a per-connection key on native Windows). A session started as one OS user cannot see or message a session started as another, even sharing the same terminal multiplexer. ### Threat Model The core risk is **cross-session prompt injection**: a compromised, misconfigured, or simply overzealous peer session sends text designed to get the receiving session to act outside what its own user authorized. | Threat | Risk | Mitigation | |--------|------|------------| | **Peer suggests a destructive or risky action** | A compromised peer session tries to get another session to run a command, touch a file, or approve something it shouldn't | Text-only channel: a message can never approve a permission prompt or change configuration. The receiving session's own permission rules still apply to anything it's asked to do. | | **Command injection via message text** | A message body contains something that looks like a slash command or shell instruction | Claude Code never executes text arriving in a message; it is delivered as plain text, same as any other prompt content. | | **Socket spoofing / stale endpoint** | A reply is routed to the wrong process because a socket path was replaced or a session restarted | `SendMessage` verifies the endpoint before delivering and refuses on a symlinked target, an unexpected connected process, or an endpoint whose identity can't be read, rather than sending blind. | | **Unsolicited flood from a peer** | A misbehaving or looping peer sends messages faster than the recipient can process | Burst refusal at the sender once a same-machine inbox's capacity is reached; at the recipient, repeated messages from one sender are rate-limited, identical repeats within a short window are dropped, and at most 50 accepted messages queue for Claude to read. | | **Cross-machine exposure via Remote Control** | Messages to another of your machines or the web pass through Anthropic's infrastructure rather than staying local | Same-machine traffic never leaves the box; cross-machine traffic is HTTPS through the same relay Remote Control already uses. Set `isolatePeerMachines: true` to require explicit approval before anything crosses a machine boundary. | | **Silent acceptance of untrusted peers** | A session with permissive defaults accepts messages from any session that can reach it | `crossSessionInbound: "refuse"` drops all inbound peer messages; `"hold"` requires a per-message **Approve**; the receiving session's permission-mode class sets the default when nothing else applies (a session that bypasses prompts holds by default, one that prompts delivers by default). | The design constraint that makes this tractable: a cross-session message is informational only. It is never treated as user consent, and the receiving session is explicitly instructed never to change its own permission settings, `CLAUDE.md`, or other configuration because a peer asked. ### Best Practices ```bash # 1. Lock down a sensitive session's inbound side explicitly # In that project's settings.json: # { "crossSessionInbound": "refuse" } # 2. Require approval before any message leaves the machine # { "isolatePeerMachines": true } # 3. Turn the whole feature off for a session or an organization # { "permissions": { "deny": ["SendMessage", "ListAgents"] }, "crossSessionInbound": "refuse" } # Denying SendMessage also removes messaging to subagents and agent-team teammates. # 4. Don't assume a quiet /status means the feature is off # A refusing session shows no visible change in its own /status or in peers' /list-agents. # Confirm via the settings files that apply, not by observing behavior. ``` ### Enterprise Considerations Same-machine messaging never leaves the box and needs no Remote Control connection. Cross-machine and web messaging route through Anthropic's relay, the same one Remote Control already uses; organizations with data-residency constraints on that relay should treat cross-session messaging like any other Remote-Control-adjacent traffic and consider the managed-settings lockdown above. `crossSessionInbound` and permission deny rules on `SendMessage`/`ListAgents` both apply from managed settings, so this is enforceable at the org level without relying on individual developers to configure it. --- *Version 1.2.0 | February 2026 | Part of [Claude Code Ultimate Guide](../README.md)*