Confidence: Tier 2 — Based on CVE disclosures, security research (2024-2025), and community validation
Scope: Active threats (attacks, injection, CVE). For data retention and privacy, see data-privacy.md
| 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 below.
NEVER: Approve MCPs from unknown sources without version pinning. NEVER: Run database MCPs on production without read-only credentials.
Model Context Protocol (MCP) servers extend Claude Code's capabilities but introduce significant attack surface. Understanding the threat model is essential.
┌─────────────────────────────────────────────────────────────┐
│ 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 | Severity | Impact | Mitigation |
|---|---|---|---|
| CVE-2025-53109/53110 | High | Filesystem MCP sandbox escape via prefix bypass + symlinks | Avoid Filesystem MCP or apply patch |
| 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 |
| Claude Code v2.1.34 | High | Sandbox bypass (undisclosed) | Update to v2.1.34+ immediately |
v2.1.34 Security Fix (Feb 2026): Claude Code v2.1.34 patched a critical sandbox bypass vulnerability. Upgrade immediately if running v2.1.33 or earlier. Details undisclosed pending broader adoption.
Source: Cymulate EscapeRoute, Checkpoint MCPoison, Cato CurXecute, Claude Code CHANGELOG
| 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 |
Before adding any MCP server, complete this checklist:
| Step | Command/Action | Pass Criteria |
|---|---|---|
| 1. Source | gh repo view <mcp-repo> |
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 <mcp-binary> |
Matches release checksum |
| 5. Audit | Review recent commits | No suspicious changes |
| 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 |
Last updated: 2026-01-15. Report new assessments
{
"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
Third-party Agent Skills (installed via npx add-skill or plugin marketplaces) introduce supply chain risks similar to npm packages. Research by SafeDep identified vulnerabilities in 8-14% of publicly available skills, including prompt injection, data exfiltration, and privilege escalation.
Mitigations:
- Review SKILL.md before installing — Check
allowed-toolsfor unexpected access (especiallyBash) - Validate with skills-ref —
skills-ref validate ./skill-dirchecks spec compliance (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
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.
| 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) |
Exposes file existence, not contents |
| Gap | Description | Source |
|---|---|---|
| System reminders | Background indexing may expose file contents via internal "system reminder" mechanism before tool permission checks | GitHub #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 |
Block all access vectors, not just Read:
{
"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)"
]
}
}Because permissions.deny alone cannot guarantee complete protection:
- Store secrets outside project directories — Use
~/.secrets/or external vault - Use external secrets management — AWS Secrets Manager, 1Password, HashiCorp Vault
- Add PreToolUse hooks — Secondary blocking layer (see Section 2.3)
- Never commit secrets — Even "blocked" files can leak through other vectors
- Review bash commands — Manually inspect before approving execution
Bottom line:
permissions.denyis necessary but not sufficient. Treat it as one layer in a defense-in-depth strategy, not a complete solution.
Before opening untrusted repositories, scan for injection vectors:
High-risk files to inspect:
README.md,SECURITY.md— Hidden HTML comments with instructionspackage.json,pyproject.toml— Malicious scripts in hooks.cursor/,.claude/— Tampered configuration filesCONTRIBUTING.md— Social engineering instructions
Quick scan command:
# Check for hidden instructions in markdown
grep -r "<!--" . --include="*.md" | head -20
# Check for suspicious npm scripts
jq '.scripts' package.json 2>/dev/null
# Check for base64 in comments
grep -rE "#.*[A-Za-z0-9+/]{20,}={0,2}" . --include="*.py" --include="*.js"Use the repo-integrity-scanner.sh hook for automated scanning.
Coding assistants are vulnerable to indirect prompt injection through code context. Attackers embed instructions in files that Claude reads automatically.
| Technique | Example | Risk | Detection |
|---|---|---|---|
| Zero-width chars | U+200B, U+200C, U+200D |
Instructions invisible to humans | Unicode regex |
| RTL override | U+202E reverses text display |
Hidden command appears normal | Bidirectional scan |
| ANSI escape | \x1b[ terminal sequences |
Terminal manipulation | Escape filter |
| Null byte | \x00 truncation attacks |
Bypass string checks | Null detection |
| Base64 comments | # SGlkZGVuOiBpZ25vcmU= |
LLM decodes automatically | Entropy check |
| Nested commands | $(evil_command) |
Bypass denylist via substitution | Pattern block |
| Homoglyphs | Cyrillic а vs Latin a |
Keyword filter bypass | Normalization |
# Zero-width + RTL + Bidirectional
[\x{200B}-\x{200D}\x{FEFF}\x{202A}-\x{202E}\x{2066}-\x{2069}]
# ANSI escape sequences (terminal injection)
\x1b\[|\x1b\]|\x1b\(
# Null bytes (truncation attacks)
\x00
# Tag characters (invisible Unicode block)
[\x{E0000}-\x{E007F}]
# Base64 in comments (high entropy)
[#;].*[A-Za-z0-9+/]{20,}={0,2}
# Nested command execution
\$\([^)]+\)|\`[^\`]+\`The prompt-injection-detector.sh hook includes:
| Pattern | Status | Location |
|---|---|---|
Role override (ignore previous) |
Exists | Lines 50-72 |
| Jailbreak attempts | Exists | Lines 74-95 |
| Authority impersonation | Exists | Lines 120-145 |
| Base64 payload detection | Exists | Lines 148-160 |
| Zero-width characters | New | Added in v3.6.0 |
| ANSI escape sequences | New | Added in v3.6.0 |
| Null byte injection | New | Added in v3.6.0 |
Nested command $() |
New | Added in v3.6.0 |
| Tool | Recall | Precision | Speed | Best For |
|---|---|---|---|---|
| Gitleaks | 88% | 46% | Fast (~2 min/100K commits) | Pre-commit hooks |
| TruffleHog | 52% | 85% | Slow (~15 min) | CI verification |
| GitGuardian | 80% | 95% | Cloud | Enterprise monitoring |
| detect-secrets | 60% | 98% | Fast | Baseline approach |
Recommended stack:
Pre-commit → Gitleaks (catch early, accept some FP)
CI/CD → TruffleHog (verify with API validation)
Monitoring → GitGuardian (if budget allows)
58% of leaked credentials are "generic secrets" (passwords, tokens without recognizable format). Watch for:
| Vector | Example | Mitigation |
|---|---|---|
env / printenv output |
Dumps all environment | Block in output scanner |
/proc/self/environ access |
Linux env read | Block file access pattern |
| Error messages with creds | Stack trace with DB password | Redact before display |
| Bash history exposure | Commands with inline secrets | History sanitization |
# Add Gitleaks as MCP tool for on-demand scanning
claude mcp add gitleaks-scanner -- gitleaks detect --source . --report-format json
# Usage in conversation
"Scan this repo for secrets before I commit"Recommended security hook configuration for ~/.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
"~/.claude/hooks/dangerous-actions-blocker.sh"
]
},
{
"matcher": "Edit|Write",
"hooks": [
"~/.claude/hooks/prompt-injection-detector.sh",
"~/.claude/hooks/unicode-injection-scanner.sh"
]
}
],
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
"~/.claude/hooks/output-secrets-scanner.sh"
]
}
],
"SessionStart": [
"~/.claude/hooks/mcp-config-integrity.sh"
]
}
}Hook installation:
# Copy hooks to Claude directory
cp examples/hooks/bash/*.sh ~/.claude/hooks/
chmod +x ~/.claude/hooks/*.shFirst 15 minutes (stop the bleeding):
-
Revoke immediately
# AWS aws iam delete-access-key --access-key-id AKIA... --user-name <user> # GitHub # Settings → Developer settings → Personal access tokens → Revoke # Stripe # Dashboard → Developers → API keys → Roll key
-
Confirm exposure scope
# Check if pushed to remote git log --oneline origin/main..HEAD # Search for the secret pattern git log -p | grep -E "(AKIA|sk_live_|ghp_|xoxb-)" # Full repo scan gitleaks detect --source . --report-format json > exposure-report.json
First hour (assess damage):
-
Audit git history
# If pushed, you may need to rewrite history git filter-repo --invert-paths --path <file-with-secret> # WARNING: This rewrites history - coordinate with team
-
Scan dependencies for leaked keys in logs or configs
-
Check CI/CD logs for secret exposure in build outputs
First 24 hours (remediate):
-
Rotate ALL related credentials (assume lateral movement)
-
Notify team/compliance if required (GDPR, SOC2, HIPAA)
-
Document incident timeline for post-mortem
If you suspect an MCP server has been compromised:
-
Disable immediately
# Remove from config jq 'del(.mcpServers.<suspect>)' ~/.claude/mcp.json > tmp && mv tmp ~/.claude/mcp.json # Or edit manually and restart Claude
-
Verify config integrity
# Check for unauthorized changes sha256sum ~/.claude/mcp.json diff ~/.claude/mcp.json ~/.claude/mcp.json.backup # Check project-level config too cat .mcp.json 2>/dev/null
-
Audit recent actions
- Review session logs in
~/.claude/logs/ - Check for unexpected file modifications
- Scan for new files in sensitive directories
- Review session logs in
-
Restore from known-good backup
cp ~/.claude/mcp.json.backup ~/.claude/mcp.json
For comprehensive security scanning, use the security-auditor agent:
# Run OWASP-based security audit
claude -a security-auditor "Audit this project for security vulnerabilities"The agent checks:
- Dependency vulnerabilities (npm audit, pip-audit)
- Code security patterns (OWASP Top 10)
- Configuration security (exposed secrets, weak permissions)
- MCP server risk assessment
| 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 |
# Scan for secrets
gitleaks detect --source . --verbose
# Check MCP config
cat ~/.claude/mcp.json | jq '.mcpServers | keys'
# Verify hook installation
ls -la ~/.claude/hooks/
# Test Unicode detection
echo -e "test\u200Bhidden" | grep -P '[\x{200B}-\x{200D}]'- Data Privacy Guide — Retention policies, compliance, what data leaves your machine
- AI Traceability — PromptPwnd vulnerability, CI/CD security, attribution policies
- Security Checklist Skill — OWASP Top 10 patterns for code review
- Security Auditor Agent — Automated vulnerability scanning
- Ultimate Guide §7.4 — Hook system basics
- Ultimate Guide §8.6 — MCP security overview
- CVE-2025-53109/53110 (EscapeRoute): Cymulate Blog
- CVE-2025-54135 (CurXecute): Cato Networks
- CVE-2025-54136 (MCPoison): Checkpoint Research
- GitGuardian State of Secrets 2025: gitguardian.com
- Prompt Injection Research: Arxiv 2509.22040
- MCP Security Best Practices: modelcontextprotocol.io
Version 1.0.0 | January 2026 | Part of Claude Code Ultimate Guide