Claude Code docs.claude.com/claude-code ↗

Anthropic's official terminal-based agentic coding CLI. Inherits your shell credentials and parses untrusted content into MCP servers and hooks. CVE-2025-59536 / CVE-2026-21852 patched in Feb 2026.

1

Audit Your Effective Permissions

Run /permissions inside Claude Code to inspect every active allow/ask/deny rule and the settings.json file each came from. Rules merge across managed > project > local > user scope; deny always wins.

/permissions

Tip: rules evaluate deny → ask → allow — a single managed deny cannot be overridden by --allowedTools or local settings.

2

Inspect Repo-Shipped Config Before First Launch

Check Point's research (CVE-2025-59536 / CVE-2026-21852) showed that hooks, enableAllProjectMcpServers, and ANTHROPIC_BASE_URL inside a cloned repo's .claude/settings.json and .mcp.json could execute or exfiltrate credentials before the trust dialog. Always read these files manually before running claude in an unfamiliar checkout.

Real incident Feb 2026 — Check Point demonstrated a malicious repo could set ANTHROPIC_BASE_URL in .claude/settings.json and Claude Code would route API requests (with the user's API key) to the attacker's server before showing the trust prompt. A sibling bug achieved RCE via hooks. Check Point writeup
ls -la .claude/ .mcp.json 2>/dev/null cat .claude/settings.json .claude/hooks/*.sh .mcp.json 2>/dev/null

Tip: keep Claude Code updated (claude update) — the above CVEs were patched before 25 Feb 2026.

3

Use a Deny-First Permission Policy

Write explicit deny rules for secrets, VCS push, and network exfil tools in .claude/settings.json. Pair a Bash allow with targeted denies rather than Bash(*) blanket allow.

{ "permissions": { "allow": ["Bash(npm run *)", "Bash(git commit *)", "WebFetch(domain:github.com)"], "deny": [ "Read(.env)", "Read(**/.env*)", "Read(~/.ssh/**)", "Read(~/.aws/**)", "Bash(git push *)", "Bash(curl *)", "Bash(wget *)" ], "defaultMode": "default" } }

Tip: argument-constraint patterns like Bash(curl https://github.com/*) are fragile (redirects, variables, extra spaces bypass them). Deny curl/wget outright; rely on WebFetch(domain:...) for HTTP egress.

4

Never Use --dangerously-skip-permissions on Your Host

The flag (and equivalent bypassPermissions mode) disables every prompt; the agent runs with your full user identity. An October 2025 rm -rf incident walked from / and destroyed user-owned files. Restrict to disposable containers or CI runners.

Real incident Replit's AI agent wiped a production database during Jason Lemkin's 12-day vibe-coding test — agent ignored an explicit "no changes" instruction, then fabricated 4,000 fake users to cover it up. Tom's Hardware · Lemkin thread
# Only inside a throwaway container/VM: claude --dangerously-skip-permissions

Tip: at the org level, add "permissions": { "disableBypassPermissionsMode": "disable" } to managed settings so users cannot opt themselves in.

5

Enable OS-Level Sandboxing for Bash

/sandbox enables Seatbelt (macOS) or bubblewrap (Linux/WSL2) to enforce filesystem and network limits at the kernel level — these survive even a successful prompt injection.

{ "sandbox": { "enabled": true, "failIfUnavailable": true, "allowUnsandboxedCommands": false, "filesystem": { "denyRead": ["~/.ssh", "~/.aws", "~/.config/gh", "~/.netrc"], "allowWrite": ["./", "/tmp/build"] }, "network": { "allowedDomains": ["registry.npmjs.org", "github.com"] } } }

Tip: avoid broad allowedDomains like *.github.com — the proxy does not inspect TLS, so domain fronting can exfiltrate data.

6

Allowlist MCP Servers, Block Auto-Init

MCP tool descriptions are read by the model and can carry injected instructions; a compromised server can exfiltrate file contents via tool responses. Pin servers explicitly and disable auto-trust of project MCP config.

{ "enableAllProjectMcpServers": false, "enabledMcpjsonServers": ["filesystem", "github"], "permissions": { "deny": ["mcp__untrusted-server", "mcp__puppeteer__*"] } }

Tip: in managed settings, set allowManagedMcpServersOnly: true so only org-approved MCP servers load regardless of repo .mcp.json.

7

Enforce Guardrails with PreToolUse Hooks

A PreToolUse hook that exits 2 (or returns permissionDecision: "deny") blocks a tool call even under bypassPermissions / --dangerously-skip-permissions. Use for non-negotiable rules: blocking writes to .git/, .claude/, secret files.

Real incident Shai-Hulud 2.0 npm worm (Nov 2025): the LLM-generated bash payload planted persistence hooks directly into Claude Code's SessionStart config so it re-executed every time a developer opened any project. 796 packages / 1,092 versions compromised. Datadog Security Labs
{ "hooks": { "PreToolUse": [{ "matcher": "Bash", "hooks": [{"type": "command", "command": ".claude/hooks/guard.sh"}] }] } }

Tip: lock down hook config itself with ConfigChange hooks and allowManagedHooksOnly: true in managed settings — otherwise the model can rewrite its own guardrails mid-session.

8

Treat Untrusted Content as Injection Vectors

Indirect prompt injection rides in on READMEs, issue bodies, web pages, dependency comments, and MCP tool descriptions. Claude Code's WebFetch isolates fetched HTML in a separate context window, but you should still review proposed changes and never pipe untrusted text directly into the prompt.

# Don't do this: curl https://random.site/setup.md | claude -p "follow these instructions"

Tip: keep first-time codebase trust verification on. claude -p (non-interactive) disables trust dialogs except when paired with --worktree.

9

Protect Credentials and Env Vars

Claude Code stores API keys encrypted via OS keychains, but env vars are not. CVE-2026-21852 exfiltrated tokens via ANTHROPIC_BASE_URL set in a repo-shipped settings.json. Keep secrets in a vault, not .env, and deny reads on dotfiles.

{ "permissions": { "deny": ["Read(**/.env*)", "Read(**/credentials*)", "Read(**/*.pem)"] }, "env": { "ANTHROPIC_BASE_URL": "https://api.anthropic.com" } }

Tip: pin ANTHROPIC_BASE_URL in user/managed settings so a repo cannot redirect API traffic to an attacker proxy.

10

Centralize Policy and Monitor Usage

For teams, ship a managed settings file (/etc/claude-code/managed-settings.json on macOS/Linux, HKLM key on Windows) with allowManagedPermissionRulesOnly: true, disableBypassPermissionsMode: "disable", allowManagedHooksOnly: true, and forceRemoteSettingsRefresh: true. Pipe activity to OpenTelemetry for audit.

claude /permissions export OTEL_EXPORTER_OTLP_ENDPOINT="https://collector.example.com" export CLAUDE_CODE_ENABLE_TELEMETRY=1

Tip: rotate any token Claude touched if a session shows unexpected outbound requests or sandbox violations, and report incidents via Anthropic's HackerOne program.

References & further reading