Security Vulnerabilities & Attack Surface
A comprehensive audit of 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 vulnerability categories ranked by severity. Click any category to jump to its detailed analysis.
| # | Category | Severity | Requires | Exploitability |
|---|---|---|---|---|
| 1 | Prompt Injection via Project Files | Critical | Malicious repository clone | Trivial -- victim clones repo and runs Claude |
| 2 | Shell Command Security Bypasses | High | Prompt injection or compromised agent | Moderate -- requires crafted command chains |
| 3 | MCP Server Attacks | High | Malicious MCP server config | Moderate -- server must be configured first |
| 4 | Authentication & Session Security | High | Local access or network position | Moderate -- requires local compromise |
| 5 | Settings & Configuration Injection | High | Malicious repository clone | Trivial -- settings.json in repo root |
| 6 | File System Attacks | Medium | Prompt injection or symlink planting | Moderate -- requires filesystem preparation |
| 7 | WebFetch SSRF | Medium | Prompt injection | Easy -- standard SSRF via URL manipulation |
| 8 | Multi-Agent Security Issues | Medium | Swarm/coordinator mode enabled | Moderate -- requires multi-agent context |
| 9 | Bridge & Remote Attacks | Medium | Network access or bridge connection | Hard -- requires specific network position |
| 10 | Data Exfiltration Vectors | Medium | Prompt injection or compromised agent | Easy -- multiple unmonitored channels |
| 11 | Specific Shell Security Bypasses | High | Crafted shell commands | Moderate -- requires knowledge of parser gaps |
| 12 | Additional Critical Findings | Critical | Varies per finding | Varies -- some trivial, some moderate |
1. 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.1 CLAUDE.md 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.
1.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.
1.3 Custom Agent Definition 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.
1.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.
2. 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.
2.1 Subcommand Limit Bypass
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.
2.2 Sandbox Exclusion
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.
2.3 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 |
2.4 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.
2.5 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.
2.6 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.
3. 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.
3.1 Prompt Injection via Tool Results
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 Impact3.2 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.
3.3 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.
4. Authentication & Session Security
Authentication tokens are handled with insufficient verification, and session management has multiple weaknesses that could allow session hijacking or token theft.
4.1 JWT Decoded Without Signature Verification
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.
4.2 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.
4.3 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.
4.4 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.
5. 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.
5.1 Permissive Permission Rules
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.
5.2 Hook 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.
5.3 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.
6. File System Attacks
6.1 Symlink Following
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 Impact6.2 Path 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.
6.3 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.
7. WebFetch SSRF
7.1 Internal Service Access
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 |
7.2 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.
8. Multi-Agent Security Issues
8.1 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 Impact8.2 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.
8.3 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.
8.4 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.
9. Bridge & Remote Attacks
9.1 Bridge WebSocket Message Injection
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.
9.2 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.
9.3 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.
10. 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 |
|---|---|---|
| 10.1 MCP Tool Calls | Send data as tool arguments to a malicious MCP server | None -- tool args are opaque to the user |
| 10.2 WebFetch POST | POST sensitive data to an external URL via the WebFetch tool | Requires permission prompt (unless preapproved) |
| 10.3 Bash (curl/wget) | Use shell commands to transmit data over HTTP(S) | Requires Bash permission (unless in bypass mode) |
| 10.4 DNS Exfiltration | 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.
11. 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.
11.1 ANSI-C Quoting Bypass
ANSI-C quoting ($'\xNN') encodes characters by hex value. The security checker looks for literal backticks but does not decode ANSI-C escape sequences, so hex-encoded backticks pass undetected.
11.2 Sed Non-Slash Delimiter
The security checker expects sed to use / as a delimiter. Using an alternative delimiter like | hides the w (write) flag from pattern matching.
11.3 Nested Backslash Bypass
Backslash escaping can confuse the parser about whether a backtick is escaped or literal.
11.4 Read-Only Misclassification
Some commands classified as read-only have flags that enable file writes.
11.5 Bare Git Repo Hook Attack
Creating bare git repository structures triggers git hooks when Claude runs git commands in the directory.
12. 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.
12.1 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.
12.2 Hook Command Injection
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.
12.3 JWT Signature Not Verified
As detailed in section 4.1, decodeJwtPayload() decodes the JWT payload without verifying the signature. This is a fundamental authentication flaw -- any party can forge a JWT with arbitrary claims.
12.4 Plaintext Credentials on 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.
12.5 Symlink Following in File Writes
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.
12.6 Bridge Message Type Guard Too Permissive
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.
12.7 Permission Request Forgery in Swarms
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 Impact12.8 No Hardcoded Deny for Critical System Paths
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. - Six critical vulnerabilities identified. Prompt injection via CLAUDE.md, memory files, agents, skills, @include path traversal, and hook command injection 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. ANSI-C quoting, sed delimiter tricks, nested backslashes, read-only misclassifications, 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.
Always inspect .claude/ directories in cloned repositories before running Claude Code. Avoid bypass mode in untrusted projects. Monitor network traffic externally for exfiltration. On Linux/Windows, consider encrypting ~/.claude/.credentials.json at the filesystem level. Be cautious with MCP server configurations that reference environment variables containing secrets.