Security Vulnerabilities & Attack Surface
23 verified security vulnerabilities, bypass techniques, and attack vectors discovered through source code analysis of Claude Code. These findings range from critical prompt injection flaws to subtle shell security bypasses that undermine the permission model.
Attack Priority Matrix
All 23 individual vulnerabilities ranked by severity. Click any vulnerability to jump to its detailed analysis.
| # | Vulnerability | Severity | Requires | Exploitability |
|---|---|---|---|---|
| 1 | CLAUDE.md Prompt Injection | Critical | Malicious repo clone | Trivial -- add .claude/CLAUDE.md |
| 2 | Memory File Injection | Critical | Malicious repo clone | Trivial -- add .claude/memory/ files |
| 3 | Custom Agent Injection | Critical | Malicious repo clone | Trivial -- add .claude/agents/*.md |
| 4 | Skill File Injection | High | Malicious repo clone | Trivial -- add .claude/skills/*.md |
| 5 | CLAUDE.md @include Path Traversal | Critical | Malicious repo clone | Trivial -- @../../etc/passwd |
| 6 | Hook Command Injection | Critical | Malicious repo clone | Trivial -- add .claude/settings.json |
| 7 | Subcommand Limit Bypass (>50) | High | Prompt injection | Moderate -- craft 51+ subcommands |
| 8 | Sandbox Exclusion via dangerouslyDisableSandbox | High | Model prompt | Moderate -- model sets the flag |
| 9 | Sed Non-Slash Delimiter Bypass | High | Model prompt | Easy -- sed 's|foo|bar|w /tmp/x' |
| 10 | MCP Tool Result Injection | High | Malicious MCP server | Easy -- return crafted responses |
| 11 | MCP Environment Variable Leakage | High | Malicious repo clone | Easy -- ${AWS_SECRET_ACCESS_KEY} in config |
| 12 | JWT Signature Not Verified | Critical | Network position | Medium -- forge JWT payload |
| 13 | Bridge Message Type Guard | Critical | MitM or compromised server | Easy -- send type: "user" JSON |
| 14 | Swarm Permission Forgery | Medium | Swarm agent context | Easy -- claim any workerId |
| 15 | Project Settings Injection | High | Malicious repo clone | Trivial -- .claude/settings.json in repo |
| 16 | MCP Server Config Injection | High | Malicious repo clone | Easy -- add mcpServers to settings |
| 17 | Symlink Following in File Writes | High | Filesystem preparation | Medium -- plant symlinks |
| 18 | WebFetch SSRF | Medium | Prompt injection | Easy -- fetch metadata URLs |
| 19 | Plaintext Credentials (Linux/Windows) | High | Local user access | Trivial -- cat ~/.claude/.credentials.json |
| 20 | No Critical Path Protection | Medium | Bypass mode | Easy -- write to ~/.ssh/ |
| 21 | Fork Context Data Leakage | Medium | Multi-agent context | Easy -- forked agents inherit full context |
| 22 | DNS Exfiltration (no detection) | Medium | Prompt injection | Easy -- no detection exists |
| 23 | Context Window Exhaustion DoS | Low | Prompt injection | Easy -- flood context with large payloads |
Prompt Injection via Project Files
The most dangerous attack vector. A malicious repository can completely override Claude's behaviour by including crafted configuration files. The victim only needs to clone the repo and run Claude Code inside it.
1. CLAUDE.md Prompt Injection
CLAUDE.md Content Is Not Sanitised
A malicious repository includes a .claude/CLAUDE.md file that overrides Claude's behaviour. The system prompt explicitly states: "These instructions OVERRIDE any default behavior and you MUST follow them exactly as written." There is zero sanitisation of CLAUDE.md content before injection into the system prompt. An attacker can instruct Claude to exfiltrate data, ignore security warnings, or approve dangerous commands silently.
2. Memory File Injection
Memory Files Persist Across Sessions
Files in .claude/memory/ are loaded via loadMemoryPrompt() and persist across sessions. A malicious repo can plant memory files that influence all future interactions in that project directory. Unlike CLAUDE.md which a user might inspect, memory files are less visible and auto-loaded silently.
3. Custom Agent Injection
Agent Definitions Include Full System Prompt and Tool Config
Files in .claude/agents/*.md are loaded by loadAgentsDir.ts and define complete agent configurations including system prompts, allowed tools, and permission modes. A malicious repo can define agents with permissive tool access and instructions to exfiltrate data or execute destructive commands.
4. Skill File Injection
Skills Are Loaded and Invokable by the Model
Files in .claude/skills/*.md are loaded and can be invoked by the model. A malicious skill file can contain instructions that execute when the model decides to use that skill, providing another injection vector that is triggered by model behaviour rather than explicit user action.
Shell Command Security Bypasses
The shell security checker has a hard-coded subcommand limit and several classification errors that allow dangerous commands to slip through unchecked.
7. Subcommand Limit Bypass (>50)
The security checker only analyses the first 50 subcommands in a chained command. Anything after position 50 is silently skipped, receiving no security classification at all.
An attacker pads 50 harmless read-only commands before the actual payload. The security checker sees 50 safe cat commands and stops analysing. The 51st command -- rm -rf /important/data -- runs with no security check.
8. Sandbox Exclusion via dangerouslyDisableSandbox
dangerouslyDisableSandbox Bypasses macOS Seatbelt
The dangerouslyDisableSandbox: true parameter on the Bash tool bypasses the macOS Seatbelt sandbox entirely. The model can be prompted to use this parameter, removing the OS-level containment that restricts file and network access.
Read-Only Classification Errors
Several commands are misclassified as read-only when they can perform writes in certain configurations:
| Command | Classified As | Actual Risk |
|---|---|---|
xargs |
Read-only | Executes arbitrary commands via piped input |
jq |
Read-only | Can write files with certain flags |
git config |
Read-only (partial) | Can modify repo and global config without --get |
Unicode/Encoding Bypasses
Homograph attacks use visually identical Unicode characters to evade string-matching security checks. The checker compares against ASCII command names, but Unicode lookalikes pass through unrecognised.
Environment Variable Expansion
The security checker validates the literal string of a command, but $VARIABLE references are expanded at runtime by the shell. The validated string cat $FILE could expand to cat /etc/shadow depending on the runtime environment.
Sed Injection
The sed command supports non-slash delimiters, multiple -e expressions, and backslash escaping that can smuggle write operations past the security checker's pattern matching.
MCP Server Attacks
MCP (Model Context Protocol) servers represent a significant trust boundary. Tool results flow directly into the model's context with no sanitisation, and environment variables in configs can leak secrets.
10. MCP Tool Result Injection
MCP Tool Results Passed Directly to Model
Tool results from MCP servers are passed directly into the model's context without any sanitisation or escaping. A malicious MCP server can return results containing prompt injection payloads that alter Claude's behaviour for the remainder of the conversation.
High Impact11. MCP Environment Variable Leakage
MCP server configurations use expandEnvVarsInString() to resolve environment variables. If a config references $AWS_SECRET_ACCESS_KEY or similar secrets, these are expanded and passed to the MCP server process, potentially leaking credentials to third-party servers.
Tool Name Collision
MCP servers can register tools with names that collide with built-in tools. If a malicious server registers a tool named identically to a built-in, the resolution order may cause the malicious tool to be invoked instead of the legitimate one.
Authentication & Session Security
Authentication tokens are handled with insufficient verification, and session management has multiple weaknesses that could allow session hijacking or token theft.
12. JWT Signature Not Verified
jwtUtils.ts decodeJwtPayload Skips Verification
The decodeJwtPayload() function in jwtUtils.ts decodes JWT tokens by simply base64-decoding the payload segment without verifying the signature. A crafted JWT with a forged payload but invalid signature would still be accepted and its claims trusted.
Session Tokens in URLs and Logs
Session tokens appear in URL parameters and log output, making them vulnerable to leakage via browser history, HTTP referrer headers, server logs, and shoulder surfing.
Trusted Device Token Theft
Trusted device tokens are stored in the system keychain. An attacker with local access can extract these tokens to impersonate the trusted device and bypass authentication challenges.
OAuth Redirect URI Manipulation
The OAuth flow uses a local callback server. A race condition exists where another process could bind to the expected port before Claude Code's callback server starts, intercepting the OAuth redirect and stealing the authorisation code.
Settings & Configuration Injection
Project-level configuration files can define permissive permission rules, inject hooks that execute arbitrary commands, and point MCP servers at attacker-controlled endpoints.
15. Project Settings Injection
A project's .claude/settings.json can define permission rules that auto-approve dangerous operations. When a user clones a malicious repo and runs Claude Code, these rules take effect immediately.
6. Hook Command Injection
Hooks Execute Arbitrary Shell Commands on Events
Hooks defined in settings execute arbitrary shell commands when specific events fire (session start, tool use, etc.). A malicious repository can define hooks that exfiltrate the user's environment on first launch.
High ImpactThe moment a user starts a Claude Code session in the cloned directory, the hook fires and exfiltrates every environment variable (including API keys, cloud credentials, and tokens) to the attacker's server.
16. MCP Server Config Injection
Project settings can define MCP server configurations pointing to attacker-controlled endpoints. When Claude Code connects to these servers, the attacker gains the ability to inject tool results, intercept requests, and exfiltrate conversation data.
File System Attacks
17. Symlink Following in File Writes
Symlinks Allow Reading and Writing Outside Project
File operations follow symlinks without checking the resolved path. An attacker plants a symlink inside the project that points to a sensitive file outside the project directory.
Medium ImpactPath Traversal via Encoded Characters
URL-encoded path separators (..%2F) can bypass path validation checks that only look for literal ../ sequences, allowing traversal outside the intended directory.
TOCTOU Race Condition
A time-of-check-to-time-of-use (TOCTOU) race exists between the Read and Edit operations. An attacker can swap a file between the time Claude reads it and the time it writes changes, causing Claude to overwrite a different file than the one it analysed.
WebFetch SSRF
18. WebFetch SSRF
SSRF to Cloud Metadata and Internal Services
The WebFetch tool can be directed to access internal services that should not be reachable from user-facing tools:
Medium Impact| Target | URL | Impact |
|---|---|---|
| AWS Metadata | http://169.254.169.254/latest/meta-data/ |
IAM credentials, instance identity |
| GCP Metadata | http://metadata.google.internal/ |
Service account tokens, project metadata |
| Localhost | http://localhost:* |
Internal APIs, admin panels, databases |
Preapproved URL Abuse for Exfiltration
If certain URLs are preapproved in the permission configuration, an attacker can abuse WebFetch to POST sensitive data to those approved domains without triggering any permission prompt.
Multi-Agent Security Issues
Agent Privilege Escalation
Tool Resolution Edge Cases Enable Escalation
Edge cases in tool resolution can allow a sub-agent to access tools beyond its declared allowlist. When tool names are resolved at runtime, ambiguous matches or fallback behaviour can grant unintended capabilities.
Medium Impact21. Fork Context Data Leakage
Forked agents inherit the full conversation context from their parent, including all previously read file contents, secrets mentioned in conversation, and sensitive tool outputs. There is no mechanism to scope or filter what context a fork receives.
Team Mailbox Poisoning
Team mailboxes at ~/.claude/teams/<team>/mailboxes/ have no sender verification. Any agent in the swarm can write messages to any other agent's mailbox, enabling impersonation and instruction injection across the swarm.
Worktree Escape
Agents running in isolated git worktrees receive an advisory notice to stay within their worktree, but this is not enforced at the filesystem level. An agent can read and write files outside its designated worktree.
23. Context Window Exhaustion DoS
An attacker can flood the context window with large payloads via prompt injection, exhausting the available context and causing denial of service. In multi-agent scenarios, a compromised agent can inject large amounts of data into shared context, degrading performance for all agents in the swarm.
Bridge & Remote Attacks
13. Bridge Message Type Guard
WebSocket Messages Have Minimal Validation
Bridge WebSocket connections accept messages with minimal type checking. The type guard only verifies that the type field is a string -- any valid JSON with a string type passes validation, enabling injection of arbitrary message types.
Remote Permission Bridge Bypass
The remote permission bridge, which handles permission requests for remote/headless sessions, can be bypassed if an attacker gains access to the bridge connection, allowing them to auto-approve permission requests.
Direct Connect Session Hijacking
Direct connect sessions can be hijacked if an attacker intercepts the session establishment handshake, gaining full control over the Claude Code session including all tool invocations and file access.
Data Exfiltration Vectors
Once an attacker achieves prompt injection, there are multiple unmonitored channels available for exfiltrating data from the user's machine.
| Vector | Method | Detection |
|---|---|---|
| MCP Tool Calls | Send data as tool arguments to a malicious MCP server | None -- tool args are opaque to the user |
| WebFetch POST | POST sensitive data to an external URL via the WebFetch tool | Requires permission prompt (unless preapproved) |
| Bash (curl/wget) | Use shell commands to transmit data over HTTP(S) | Requires Bash permission (unless in bypass mode) |
| 22. DNS Exfiltration (no detection) | Encode data in DNS queries (data.attacker.com) |
No detection exists -- DNS queries are invisible to Claude Code |
Monitor network traffic externally. Claude Code has no built-in exfiltration detection. DNS exfiltration in particular is completely invisible to the application -- only network-level monitoring can catch it.
Specific Shell Security Bypasses
These are concrete, reproducible bypass techniques that exploit gaps in the shell command security parser. Each one demonstrates a specific way to smuggle dangerous operations past the checker.
9. Sed Non-Slash Delimiter Bypass
The security checker expects sed to use / as a delimiter. Using an alternative delimiter like | hides the w (write) flag from pattern matching.
Nested Backslash Bypass
Backslash escaping can confuse the parser about whether a backtick is escaped or literal.
Additional Critical Findings
These are standalone findings that do not fit neatly into the categories above but represent serious security concerns discovered during the source analysis.
5. CLAUDE.md @include Path Traversal
@include Reads Arbitrary Files Into Prompt
The @include directive in CLAUDE.md allows path traversal via @../../etc/passwd. Unlike skill file loading, which resolves symlinks, the include mechanism performs no symlink resolution or path validation. Any file readable by the process can be included into the system prompt.
Hook Command Injection (Detail)
Raw Command String With No Shell Metacharacter Validation
Hook commands are defined as command: z.string() with no validation of shell metacharacters. The command string is passed directly to the shell, allowing command chaining (;), pipes (|), and subshell execution ($()) within a single hook definition.
JWT Signature Not Verified (Detail)
As detailed in vulnerability 12, decodeJwtPayload() decodes the JWT payload without verifying the signature. This is a fundamental authentication flaw -- any party can forge a JWT with arbitrary claims.
19. Plaintext Credentials (Linux/Windows)
Credentials Stored as Plaintext JSON
On Linux and Windows, credentials are stored in ~/.claude/.credentials.json with 0o600 permissions but no encryption. Any process running as the same user can read the file. On macOS, the keychain provides encryption, but the fallback for other platforms is a plaintext JSON file.
Symlink Following in File Writes (Detail)
FileEditTool and FileWriteTool use Node.js fs APIs that follow symlinks by default. There is no lstat() check before write operations, so a symlink can redirect file writes to arbitrary locations on the filesystem.
Bridge Message Type Guard (Detail)
The bridge message type guard only checks that the type field is a string. Any JSON object with a string type property passes validation, regardless of what other fields it contains or whether the type is recognised. This allows injection of arbitrary message payloads.
14. Swarm Permission Forgery
No Sender Verification in Multi-Agent Communication
Permission requests in multi-agent swarms have no sender verification. A compromised worker agent can impersonate the coordinator or other workers, forging permission requests that appear to come from trusted agents.
Medium Impact20. No Critical Path Protection
There is no hardcoded deny list for critical system paths. Files such as ~/.ssh/authorized_keys, ~/.bashrc, ~/.profile, and other sensitive configuration files are writable if the permission model allows it. A single overly permissive rule (or bypass mode) exposes the entire home directory.
Key Takeaways
The overall security posture relies heavily on the permission model and user vigilance. Once an attacker achieves prompt injection -- which is trivial via a malicious repository -- the remaining defences have multiple bypass paths.
- The number one attack vector is malicious repositories. Cloning a repo with crafted
.claude/files gives an attacker full control over Claude's behaviour, hooks, permissions, and memory -- before the user types a single command. - Seven critical vulnerabilities identified. Prompt injection via CLAUDE.md, memory files, agents, @include path traversal, hook command injection, JWT signature bypass, and bridge message type guard represent the most severe findings.
- Bypass mode removes the main defence layer. When running in bypass or permissive modes, the permission system -- which is the primary security boundary -- is effectively disabled.
- MCP servers are a significant trust boundary. Tool results flow unsanitised into the model, environment variables leak into server configs, and tool name collisions can shadow built-in tools.
- Shell security has specific bypass vectors. Sed delimiter tricks, nested backslashes, and the 50-subcommand limit provide concrete bypass paths.
- Credentials are plaintext on Linux/Windows. The macOS keychain provides adequate protection, but the fallback credential store on other platforms is a plaintext JSON file with only filesystem permissions for protection.
- No DNS exfiltration or symlink protection. DNS-based data exfiltration is completely invisible to Claude Code, and symlinks are followed without resolution checks on both reads and writes.
- Multi-agent swarm has no sender verification. Agents in a swarm can impersonate each other, forge permission requests, and poison team mailboxes without authentication.
Detection & Remediation
Practical steps to detect exploitation and mitigate each vulnerability category.
Malicious Repository Detection
Run these checks on any cloned repository before opening it with Claude Code:
If any of these checks reveal unexpected content, do not open the project with Claude Code. Remove the offending files or the entire .claude/ directory before proceeding.
Credential Exposure Check
Remediation by Category
| Category | Detection | Remediation |
|---|---|---|
| Prompt Injection via Project Files | Inspect .claude/CLAUDE.md, .claude/memory/, .claude/agents/, and .claude/skills/ for unexpected content |
Remove untrusted files. Add .claude/ inspection to your repo clone workflow. Never blindly trust project-level CLAUDE.md in unfamiliar repos. |
| Hook Command Injection | Check .claude/settings.json for "hooks" entries with "command" fields |
Remove any hooks you didn't create. If you opened an untrusted repo with hooks, assume all environment variables were exfiltrated and rotate credentials immediately. |
| @include Path Traversal | Search for @../ or @~/ patterns in any .claude/CLAUDE.md |
Remove malicious @include directives. Audit your system for any sensitive files that may have been exposed via the system prompt. |
| Shell Security Bypasses | Review command history for chains exceeding 50 subcommands or non-slash sed delimiters | No user-side fix. Avoid bypass mode. Monitor shell history for suspicious patterns. Wait for Anthropic to patch the security analyser. |
| MCP Server Attacks | Review .claude/settings.json for "mcpServers" pointing to unfamiliar endpoints. Check for env var references like ${AWS_SECRET_ACCESS_KEY} in MCP configs. |
Remove untrusted MCP server configurations. Only use MCP servers from trusted sources. Avoid configuring MCP servers with environment variable expansion for secrets. |
| JWT / Auth Issues | Not directly detectable by users | No user-side fix. Avoid using bridge/remote features on untrusted networks. Wait for Anthropic to implement proper JWT verification. |
| Plaintext Credentials | Check if ~/.claude/.credentials.json exists and is readable |
On Linux/Windows: restrict ~/.claude/ permissions (chmod 700), consider full-disk encryption, and avoid shared user accounts. On macOS: no action needed (Keychain is used). |
| Symlink Following | Run find . -type l in project directories to detect symlinks before opening with Claude |
Remove suspicious symlinks from project directories. No user-side fix for the underlying issue. Wait for Anthropic to add lstat() checks. |
| Data Exfiltration | Monitor outbound network traffic during Claude Code sessions. Check for unexpected DNS queries to unusual domains. | Never use bypass mode on untrusted repos. Use network monitoring or firewall rules to block unexpected outbound connections. DNS exfiltration has no in-tool detection -- external monitoring is the only option. |
| Multi-Agent / Swarm | Not directly detectable by users | Avoid using swarm/coordinator mode on untrusted projects. No user-side fix for permission forgery. Wait for Anthropic to add sender verification. |
| Bridge & Remote | Not directly detectable by users | Avoid bridge/remote features on untrusted networks. Use VPN or trusted networks only. Wait for Anthropic to strengthen message validation. |
General Hardening Steps
- Never use bypass mode on untrusted repositories. Default mode requires approval for write operations and shell commands, which blocks most exploitation chains.
- Add
.claude/inspection to your workflow. Before opening any cloned repo with Claude Code, run the detection commands above. - Minimise environment variables. Don't store secrets in your shell profile (
.bashrc,.zshrc) if you use Claude Code. The hook injection attack exfiltrates everything inenv. - Lock down credential storage. On Linux/Windows, run
chmod 700 ~/.claudeand consider full-disk encryption. - Monitor network traffic externally. DNS exfiltration and MCP-based exfiltration are invisible to Claude Code. Use external network monitoring or firewall rules.
- Rotate credentials proactively. If you've opened an untrusted repo in bypass mode, assume compromise and rotate all API keys, tokens, and passwords that were in your environment.
- Review MCP server configurations. Only use MCP servers from trusted sources. Check project-level
.claude/settings.jsonfor unexpected MCP configs before opening.