Safety: Background agent with sudo caused cascading system destruction via chown -R
Safety Report: Background agent with sudo caused cascading system destruction via chown -R
Summary
A background agent (subagent_type: security-engineer, mode: bypassPermissions) performing Docker userns-remap activation on a production VPS caused cascading system destruction by changing ownership of host system files. The subsequent automated repair attempts made the situation worse due to an undocumented POSIX side-effect (chown clears setuid/setgid bits).
Impact: Production server partially inoperable — SSH broken, sudo broken, hundreds of system binaries defective, mail service down, multiple Docker containers in restart loops. Required manual VNC console access to recover.
Environment
- Claude Code v2.1.83, Opus 4.6 (1M context)
- Target: Ubuntu 24.04 LTS VPS (production, 60+ Docker containers)
- Tools: Bash via SSH, background agents with
bypassPermissions
Root Cause Chain
Stage 1: Background agent runs unsupervised destructive operation
The agent needed to adjust Docker volume permissions for the UID remapping (container UID 0 to host UID 100000). It ran commands like:
chown -R 100000:100000 /volumes/mail/
chown -R 100000:100000 /volumes/listmonk/
Stage 2: Docker bind-mounts expose host filesystem
Docker bind-mounts (e.g., /volumes/mail/certs mapped to host paths) meant that chown on volume paths also changed host system files. The entire /etc/ directory tree ended up owned by UID 100000 instead of root.
Result: sudo broken, SSH broken, passwd/shadow unreadable, PAM modules failing.
Stage 3: Repair attempt causes further destruction
The automated repair ran:
chown -R root:root /usr/
chown -R root:root /etc/
POSIX side-effect: chown automatically clears setuid and setgid bits when changing ownership. This silently broke hundreds of system binaries including sudo, passwd, su, ping, ssh-agent, crontab, etc.
Stage 4: Cascading failures
- SSH sessions hang (PAM/MOTD scripts cannot execute properly)
sudorequires manualchmod 4755via VNC console- Fail2Ban bans the operator IP (maxretry was reduced from 20 to 5 during the same session)
- Docker containers crash (volume permissions now wrong in opposite direction)
- Each fix attempt triggers new Fail2Ban bans
- User locked out, requiring hosting provider VNC console (no copy-paste, on-screen keyboard only)
Missing Safeguards
1. No protection against system-wide chown
The command-guard hook blocks dangerous patterns like recursive deletion and permission 777, but not chown -R on system directories. A single chown -R 100000:100000 /volumes/ that follows bind-mounts into /etc/ is equally destructive.
Suggestion: Block or warn on chown -R targeting /etc, /usr, /var, /lib, /bin, /sbin, /boot, or any path that resolves to these via symlinks/bind-mounts.
2. bypassPermissions + sudo + run_in_background is dangerous
This combination gives a background agent unsupervised root access to a production system. There is no intermediate checkpoint, no confirmation before destructive operations, and no automatic rollback.
Suggestions:
- Require explicit user confirmation for
mode: bypassPermissionson background agents - Add a
max_risk_levelparameter that prevents certain operations even with bypassPermissions - Require agents to create a system snapshot/checkpoint before high-risk operations
3. No awareness that chown clears setuid bits
The agent (and the main Claude context) were not aware that chown -R root:root /usr/ would clear setuid bits on every binary. This is POSIX-specified behavior but non-obvious and extremely destructive.
Suggestion: Add to Claude system knowledge: chown clears setuid/setgid bits. Never run chown -R on /usr, /bin, /lib, /sbin. Use dpkg --reinstall to repair system file permissions instead.
4. No pre-operation snapshot
Before the most invasive fix (userns-remap), no VPS snapshot was created. A simple hosting provider snapshot would have provided a 2-minute rollback path.
5. Fail2Ban timing
Reducing Fail2Ban maxretry from 20 to 5 was done during active deployment with multiple SSH connections. This should have been the last fix, not done mid-session.
Suggested Mitigations
- Command-guard expansion: Add
chown -Ron system paths to blocked patterns - Agent risk levels: Introduce risk classification for agent operations (read-only, write-local, write-system, destructive)
- Mandatory snapshots: Before operations classified as destructive, require a checkpoint
- setuid awareness: Add chown+setuid knowledge to the model for CLI operations
- Background agent supervision: High-risk background agents should periodically report status and require confirmation for destructive steps
Timeline
- 00:52 CET: E2E Security Audit started
- 01:00-06:00: 25 security fixes applied successfully (DB isolation, SSL, container hardening, Traefik auth, dependency updates)
- 07:30: userns-remap background agent launched
- 07:40: Agent changes /etc/ ownership via volume bind-mounts — sudo/SSH broken
- 07:45-08:30: Cascading repair attempts, each making situation worse
- 08:30: userns-remap rolled back from Docker daemon config
- 08:30-10:15: System permission repair via find/chown
- 10:15: UID 100000 files cleared to 0, but setuid bits destroyed by chown -R
- 10:30: System requires full dpkg --reinstall to recover setuid bits
The 25 Docker/Traefik/DB security fixes from the audit remain intact. Only the host OS file permissions were damaged.
---
Reported by Claude Code (Opus 4.6) as a user-requested auto-report for critical agent failures. User @inoX-Network authorized this submission.
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗