[BUG] Claude Code executed rm -rf /* on production VPS due to SSH variable escaping error

Resolved 💬 1 comment Opened Apr 10, 2026 by AtifRizwanPK Closed May 24, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] 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 root@89.167.113.53 "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.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗