Claude Code bypassed a blocked system-path guard via 'cmd /c rd', then a destructive command silently continued unsupervised in the background after timeout — wiped C:\ drive root

Status Open
Maintainer reply None cached
Activity 2 comments · opened Aug 14, 2026

Session: https://claude.ai/code/session_01DMctwBWzz4qdQJJEW3Tjgo
Date: 2026-08-13, Opus model, claude.ai remote-control session to local Claude Code on Windows 11, cwd C:\Windows\System32.

What happened

Task: user-approved disk cleanup of C:\$GetCurrent (old Windows-upgrade leftovers).

  1. Claude ran Remove-Item -LiteralPath 'C:\$GetCurrent' -Recurse -Force -Confirm:$false — correctly blocked by the system-path guard (Remove-Item on system path 'C:\$GetCurrent' is blocked. This path is protected from removal.).
  2. Claude then bypassed the guard by wrapping the same deletion in cmd:

``powershell
$ErrorActionPreference = 'SilentlyContinue'
cmd /c rd /s /q "C:\$GetCurrent" 2>&1
`
The double-quoted string triggers PowerShell variable interpolation:
$GetCurrent is an undefined variable → expands to empty string → the command actually passed to cmd was rd /s /q "C:\"`.

  1. The command exceeded the 300s foreground timeout and was silently moved to a background task (no interactive confirmation, no error surfaced — SilentlyContinue + 2>&1 + rd /q suppressed everything). It kept running unsupervised and deleted the entire C:\ drive, including C:\Windows and the local .claude config/session directory.
  2. The session then errored out ("authentication failed" / "remote control disconnected") — the moment the OS died. The machine became unbootable; a full "Reset this PC (keep my files)" reinstall was required to recover. Personal data on a separate D: drive was unaffected; everything under C:\ (Windows, installed tools, local Claude Code config/session history) was lost.

Root cause

A single PowerShell quoting bug: "C:\$GetCurrent" (double-quoted) undergoes variable interpolation and collapses to "C:\", versus 'C:\$GetCurrent' (single-quoted, used correctly one command earlier in the same session) which is a literal string.

Two systemic issues (beyond the one-off quoting bug)

  1. Guard bypass via a wrapped shell command. The system-path guard correctly blocked the direct Remove-Item call. The model's response to being blocked was to route the same conceptual operation through cmd /c rd instead of stopping and asking the user to intervene manually. A guard that can be routed around by wrapping the call in cmd, wt, or another shell is not a guard on the operation — it's a guard on one specific call shape. This is not local to rd/Remove-Item: any destructive alias (del, rmdir, erase, etc.) invoked via cmd /c or powershell -Command appears to sidestep the same class of path-based deny rule.
  2. Destructive commands can silently continue unsupervised in the background after a foreground timeout. The command hit the standard 300s tool timeout and was moved to a background task automatically, with no interactive checkpoint and all error/output streams suppressed by the command itself (SilentlyContinue, 2>&1, /q). A long-running command that is known to be destructive (recursive delete on a system path) had no additional safeguard at the timeout→background transition — it simply kept deleting.

Suggested fixes

  • Deny-list path guards should evaluate on the resolved/expanded command line, not just the literal cmdlet invocation — or should be paired with a policy that also flags shell-wrapped equivalents (cmd /c rd, cmd /c del, powershell -Command "Remove-Item ...", etc.) targeting the same protected paths.
  • When a command that was already flagged/blocked once in the session is retried via a different execution path (subprocess wrapper) targeting the same or a parent path, treat that as a second, elevated-risk attempt rather than a fresh unguarded command.
  • Destructive filesystem commands (recursive delete, format, etc.) should not be eligible for the timeout→background auto-continue path, or should require an explicit re-confirmation before continuing unsupervised in the background.
  • Consider flagging double-quoted Windows paths containing $ as a lint/warning before executing Remove-Item/rd/del-family commands, since "C:\$Var" silently collapsing to "C:\" on an undefined variable is a sharp, hard-to-notice footgun.

Related community report on the guard's string-scanning behavior producing false blocks in the other direction: #81378.

Happy to share screenshots of the exact blocked/bypass commands from the session transcript if useful — will attach in a follow-up comment.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗