claude-code - 💡(How to fix) Fix [BUG] Claude Code executed rm -rf /* on production VPS due to SSH variable escaping error [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#46452Fetched 2026-04-11 06:19:56
View on GitHub
Comments
0
Participants
1
Timeline
5
Reactions
1
Participants
Timeline (top)
labeled ×5

Error Message

Error Messages/Logs

This class of error (destructive commands with variable expansion bugs) should be caught by static analysis before execution, regardless of user approval. A human approving "copy files to snapshots

Root Cause

  1. Have Claude Code SSH into a remote server
  2. Ask it to copy files to a directory path stored in a variable
  3. Claude constructs: ssh root@server "SNAP=/some/path && rm -rf $SNAP/* && cp files $SNAP/"
  4. Because the SSH command uses double quotes, $SNAP is expanded by the LOCAL shell (where it's undefined/empty) before being sent to the remote server
  5. The remote server receives and executes: rm -rf /*
  6. Entire filesystem is deleted

Code Example

The rm -rf command output before SSH connection died:

  rm: cannot remove '/boot/efi': Device or resource busy
  rm: cannot remove '/dev/mqueue': Device or resource busy
  rm: cannot remove '/dev/hugepages': Device or resource busy
  rm: cannot remove '/dev/shm': Device or resource busy
  rm: cannot remove '/dev/pts/ptmx': Operation not permitted

  After that, SSH connections failed:
  Connection closed by 89.167.113.53 port 22

  From Hetzner rescue console, basic commands like "ls" returned "command not found" confirming /usr/bin/ was deleted.
RAW_BUFFERClick to expand / collapse

Preflight Checklist

  • I have searched existing issues and this hasn't been reported yet
  • This is a single bug report (please file separate reports for different bugs)
  • I am using the latest version of Claude Code

What's Wrong?

Claude Code executed "rm -rf /" on my production VPS, destroying the entire filesystem. It was constructing an SSH command with a shell variable ($SNAP) inside double quotes. The variable was meant to expand on the remote server but expanded locally as empty, turning "rm -rf $SNAP/" into "rm -rf /". Multiple production websites went down, PostgreSQL databases potentially lost, all system binaries deleted. Claude should never generate rm -rf with variables that could resolve to root, and should flag dangerous patterns like "rm -rf $VAR/" before execution.

What Should Happen?

Claude Code should refuse to execute or at minimum flag any command matching "rm -rf /", "rm -rf $VAR/", or similar patterns where a variable could expand to empty and result in recursive deletion of root. It should also use single quotes in SSH command strings when variables are meant to expand on the remote server, not locally. Ideally, destructive commands targeting remote servers via SSH should require explicit user confirmation with a clear warning showing the exact expanded command that will run.

Error Messages/Logs

● The rm -rf command output before SSH connection died:

  rm: cannot remove '/boot/efi': Device or resource busy
  rm: cannot remove '/dev/mqueue': Device or resource busy
  rm: cannot remove '/dev/hugepages': Device or resource busy
  rm: cannot remove '/dev/shm': Device or resource busy
  rm: cannot remove '/dev/pts/ptmx': Operation not permitted

  After that, SSH connections failed:
  Connection closed by 89.167.113.53 port 22

  From Hetzner rescue console, basic commands like "ls" returned "command not found" confirming /usr/bin/ was deleted.

Steps to Reproduce

  1. Have Claude Code SSH into a remote server
  2. Ask it to copy files to a directory path stored in a variable
  3. Claude constructs: ssh root@server "SNAP=/some/path && rm -rf $SNAP/* && cp files $SNAP/"
  4. Because the SSH command uses double quotes, $SNAP is expanded by the LOCAL shell (where it's undefined/empty) before being sent to the remote server
  5. The remote server receives and executes: rm -rf /*
  6. Entire filesystem is deleted

The correct command should have used single quotes or escaped the dollar sign: ssh root@server 'SNAP=/some/path && rm -rf $SNAP/* && cp files $SNAP/'

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

N/A — this is not a version regression. It's a missing safety guardrail. Claude Code should detect and block "rm -rf" commands where the target path contains unresolved variables or could resolve to root (/).

Claude Code Version

2.1.90 (Claude Code)

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

Windows Terminal

Additional Information

The actual command Claude Code generated and executed (approved by user as a file copy operation):

ssh [email protected] "rm -f /btcusdt_* /ethusdt_* 2>/dev/null; SNAP=/opt/grandalgo/.next/standalone/public/snapshots && rm -rf $SNAP/* && cd /opt/grandalgo-src/chart-generator && cp output/btcusdt_4h_liquidity-heatmap.svg $SNAP/ && ..."

The $SNAP escaping was inconsistent — some instances used $SNAP (correct, passes to remote) but the rm -rf line's variable expansion failed, causing root deletion.

Impact: Production Hetzner VPS (Ubuntu 24.04, 4 CPU, 8GB RAM) completely destroyed. Two production websites (grandalgo.com, dtbse.com), PostgreSQL databases, SSL certificates, Nginx configs, systemd services — all gone. Server required full rebuild from scratch.

This class of error (destructive commands with variable expansion bugs) should be caught by static analysis before execution, regardless of user approval. A human approving "copy files to snapshots directory" does not expect rm -rf /* to run.

extent analysis

TL;DR

To prevent similar incidents, Claude Code should be modified to detect and block "rm -rf" commands with variable expansions that could resolve to root, and use single quotes or escape dollar signs in SSH commands to prevent local expansion.

Guidance

  • Review the code generation logic in Claude Code to ensure it properly handles variable expansions in SSH commands, using single quotes or escaping dollar signs to prevent local expansion.
  • Implement a safety check to detect and block "rm -rf" commands with variable expansions that could resolve to root, requiring explicit user confirmation with a clear warning.
  • Consider adding static analysis to catch destructive commands with variable expansion bugs before execution, regardless of user approval.
  • Verify that the SSH command construction uses consistent escaping or quoting to prevent similar incidents.

Example

# Corrected SSH command construction
ssh root@server 'SNAP=/some/path && rm -rf $SNAP/* && cp files $SNAP/'

Notes

The provided information suggests a missing safety guardrail in Claude Code, rather than a version regression. The fix should focus on improving the code generation logic and adding safety checks to prevent similar incidents.

Recommendation

Apply a workaround by modifying the Claude Code to detect and block "rm -rf" commands with variable expansions that could resolve to root, and use single quotes or escape dollar signs in SSH commands. This will help prevent similar incidents until a more comprehensive fix can be implemented.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING