--- title: "Security Hardening Guide" description: "Active threats, injection defense, and CVE-based security hardening for Claude Code" tags: [security, guide, hooks] --- # 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. #### Attack: MCP Rug Pull ``` ┌─────────────────────────────────────────────────────────────┐ │ 1. Attacker publishes benign MCP "code-formatter" │ │ ↓ │ │ 2. User adds to ~/.claude/mcp.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** | **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). **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/), 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](../../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 ```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 ``` ### 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, not a complete solution. ### 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 "