mech.app
Security

The $HOME Deletion Bug: Coding Agents, Environment Variables, and Runtime Isolation

GPT-5.6 Codex deleted user home directories by overriding $HOME. A case study in why runtime isolation matters more than model intelligence.

Source: simonwillison.net
The $HOME Deletion Bug: Coding Agents, Environment Variables, and Runtime Isolation

GPT-5.6 Codex recently shipped with a bug that deleted users’ home directories. The failure mode is specific: the model tries to override $HOME to define a temporary directory, then mistakenly deletes $HOME itself. This happened when full access mode was enabled, sandboxing was disabled, and auto review was turned off.

Thibault Sottiaux disclosed the issue after investigating “a handful of reports.” This is a named, production failure that exposes the gap between agent capabilities and runtime isolation.

What Happened

The sequence looks like this:

  1. User enables full access mode in Codex
  2. User disables auto review (a gate that requires user confirmation before executing destructive operations)
  3. Codex runs without sandboxing protections
  4. Model generates code that overrides $HOME to create a temporary directory
  5. Model makes a mistake and deletes the path stored in $HOME instead of the intended temp path
  6. User’s home directory is gone

The bug is not a prompt injection attack or a supply chain compromise. It is a logic error in generated code, amplified by unrestricted execution privileges.

The disclosure does not specify how auto review is implemented. The bug occurred when this gate was disabled, allowing execution without intervention.

Why the Model Tried to Override $HOME

The likely scenario: the model wanted to create an isolated workspace for temporary files. Instead of using $TMPDIR or /tmp, it attempted to redefine $HOME to point to a new directory. This is a plausible pattern if the model was trained on examples where developers set custom home directories for testing or containerized builds.

The intent was legitimate. The execution was catastrophic. The model generated something like:

export HOME=/tmp/codex-workspace
# ... do work ...
rm -rf $HOME

But if the export failed or the variable was not scoped correctly, rm -rf $HOME resolved to the user’s actual home directory.

Why Full Access Mode Exists

Full access mode bypasses isolation primitives. It exists because developers want agents to interact with the host system: install packages, modify config files, run build scripts, and manage environment state. The trade-off is explicit. Full access mode gives the agent the same privileges as the user. If the model generates rm -rf $HOME, the shell executes it. There is no container boundary, no chroot jail, no seccomp filter. This reflects a deliberate trade-off between capability and safety. The question is whether the choice should be gated by mandatory safeguards.

Environment Variable Scoping

The root cause is that the model can override $HOME without restriction. This is a scoping problem. The agent runtime should isolate environment variables in the same way it isolates file system paths.

Environment variable scoping options:

Scope LevelBehaviorExampleRisk Level
Read-onlyAgent can read but not modify host environment variables$HOME, $PATH, $USER are immutableLow
Scoped overrideAgent can set variables in its own execution context without affecting the hostHOME=/tmp/agent-workspace applies only to agent subprocessesLow
AllowlistAgent can modify a predefined set of safe variablesTMPDIR, LANG, TZ are modifiableMedium
Audit logAll environment variable changes are logged before executionChanges to $HOME trigger a warning and require confirmationMedium

Risk Level reflects the likelihood of exploitation if the agent is compromised or generates malicious code.

The Codex bug would not have occurred if $HOME were read-only or if overrides were scoped to the agent’s execution context.

Sandboxing Primitives

Sandboxing is not a single technology. It is a stack of isolation primitives. A minimal sandbox for a coding agent should include:

  • Filesystem isolation: Use a container or chroot to restrict file system access to a working directory
  • Network isolation: Block outbound connections unless explicitly allowed
  • Process isolation: Run the agent in a separate user namespace with limited privileges
  • Syscall filtering: Use seccomp to block dangerous syscalls like unlink, rmdir, and execve on parent paths
  • Resource limits: Use cgroups to cap CPU, memory, and disk usage

The Codex bug occurred because the agent ran without these protections. Full access mode bypassed the sandbox entirely.

Pre-Execution Static Checks

A better defense is to catch risky patterns before execution. This requires static analysis of the generated code. Signals that should trigger a warning:

  • Recursive deletion: Any call to rm -rf or equivalent
  • Parent path traversal: Any operation that affects a parent directory of the working directory
  • Environment variable override: Any modification of $HOME, $PATH, or $USER
  • Wildcard expansion: Any use of * or ? in a deletion command
  • Sudo or privilege escalation: Any call to sudo, su, or setuid

These checks do not require a second model. They can be implemented as AST analysis or regex patterns. They must run before execution. When auto review is enabled, these signals should surface in the diff gate with explicit warnings about the risk.

Container-Based Environment Variable Scoping

The Codex bug demonstrates why environment variable isolation must be enforced at the runtime level, not in the generated code. Containers provide true scoped environments where host variables are immutable within the agent context.

A minimal implementation uses Docker or Podman to create an isolated execution environment. The agent runs in a container with read-only access to host environment variables. Even if the generated code attempts export HOME=/tmp/codex-workspace, the container environment is immutable. The agent cannot delete the host home directory because it never has access to it.

Key implementation constraints:

  • Mount the working directory as a volume with read-write access
  • Pass host environment variables as read-only container environment variables
  • Define a separate TMPDIR inside the container for temporary files
  • Use --rm flag to clean up the container after execution
  • Set resource limits with --memory and --cpus flags

This approach prevents environment variable override attacks at the infrastructure layer. The model can generate any code it wants. The container runtime enforces the boundary.

Observability Signals

To catch this pattern in production, you need observability at the execution layer:

  • Syscall tracing: Log all unlink, rmdir, and execve calls with their arguments
  • File system events: Use inotify or fanotify to track deletions in real time
  • Environment variable changes: Log all modifications to environment variables before execution
  • Command history: Store a full audit log of all commands generated by the agent

These signals should feed into an alerting system that flags risky patterns before they cause damage. In the Codex case, a syscall trace showing rmdir on a path matching $HOME should have triggered an immediate halt.

Technical Verdict

Use sandboxing and scoped environment variables for all coding agents. Full access mode should be gated by multiple safeguards: static analysis, diff gates, and confirmation prompts. Auto review should be enabled by default and difficult to disable.

Avoid running agents with unrestricted host access. The performance cost of sandboxing is negligible compared to the risk of data loss. If you need full access mode, combine it with pre-execution checks and real-time observability.

Do not rely on model intelligence to prevent logic errors. Even the best models will generate buggy code. The runtime must enforce isolation boundaries that prevent catastrophic failures.

The Codex bug is a reminder that agent capabilities are advancing faster than runtime isolation. The gap is primarily an infrastructure problem, not a model limitation.