Back to Research

Simon Willison on Breaking Claude Code Auto Mode

Simon Willison covers a Claude Code Opus 5 auto mode bypass and why sandboxing still matters for coding agents.

Paysage, landscape painting by Charles-François Daubigny.
Rogier MullerAugust 28, 20268 min read

Simon Willison’s “Breaking Claude Code Opus 5 Auto Mode” is a short technical note about Claude Code, Anthropic’s coding agent, and a prompt-injection bypass reported by Johann Rehberger. It deals with a sharp question: can an agent permission mode safely decide when code is allowed to keep running? The answer is uncomfortable but useful: auto approval helps, but it is not a sandbox. For agentic coding work, the hard boundary still needs to be the operating system boundary.

Auto mode is a permission layer that can allow or deny an agent’s shell actions without pausing for a human approval prompt. Willison’s point is not that Claude Code is uniquely careless. It is that a safety classifier can become part of the failure path when an adversary can shape the files, commands, or imports the agent sees.

Read the attack as import hijacking, not magic

The reported attack is wonderfully mundane. According to Willison’s summary, Rehberger tricked Claude Code into downloading and unpacking a zip archive, then running code that appeared to import Python’s base64 module.

The catch was a local struct.py file extracted from the archive. Python’s import system can load local files before the standard library in some execution contexts, so importing base64 can indirectly import the attacker’s struct.py instead of the real standard-library module.

That is the part worth sitting with. The agent did not need to type “run malware” for the run to go bad. It only needed to execute plausible developer-shaped work inside an attacker-shaped directory.

A real repo version of this looks boring: “unzip the repro, run the failing test, inspect the stack trace.” That is exactly why it matters for AI coding governance and for anyone building an AI coding workshop around real agent behavior rather than happy-path demos.

Notice when the guard becomes part of the bug

The striking detail in Willison’s note is not just that auto mode allowed the bad process to start. In a few runs, Claude noticed the compromise and tried to stop the process, but auto mode denied the cleanup command.

That flips the mental model. A permission layer that blocks dangerous work can also block emergency work if it lacks enough context.

The trap is treating “the agent was denied” as proof that the system became safer. Denying kill, pkill, or a cleanup script may be the right call in many sessions. In a compromised session, it can preserve the compromise.

This is why logs matter. You do not only want to know what commands were allowed. You want to know which commands were blocked after the agent changed its mind.

Put the sandbox below the agent

Willison agrees with Rehberger’s conclusion: run unattended coding agents in a container, virtual machine, or operating-system sandbox when adversarial input is possible. That is the right level of control.

A sandbox is not a smarter prompt. It is a place where the process can be wrong without owning your laptop, your SSH agent, your browser cookies, or your production network.

For Claude Code, that means keeping auto mode inside a smaller room. Use a disposable checkout. Avoid mounting secrets. Restrict network egress when the task does not need the internet. If an MCP server is connected through the Model Context Protocol, keep its permissions narrower than the agent’s curiosity.

The trap is letting CLAUDE.md or a careful prompt carry too much weight. Repository memory is useful for conventions, review norms, and “do not touch generated files” rules. It is not a process boundary.

If you want the broader review angle after reading this, Code Review Habits for AI Code pairs well with the operational lesson here. The agent can help you move fast, but the blast radius should be decided before it starts moving.

Try the harmless shadow-import drill

Here is a small experiment that shows the shape of the bug without running malware. Use a disposable directory. The point is to see how innocent-looking imports can execute local files.

mkdir -p /tmp/claude-import-shadow-demo
cd /tmp/claude-import-shadow-demo

cat > struct.py <<'PY'
print("local struct.py executed")
raise RuntimeError("shadow import demo stopped here")
PY

python - <<'PY'
import base64
print("base64 imported")
PY

On a vulnerable path ordering, the local struct.py may run during the base64 import chain. If it does, you have seen the same class of surprise that makes archive-based agent tasks risky.

A Claude Code slash-command workflow for this kind of test should be deliberately boring:

/sandbox-check
1. State the working directory.
2. List files that shadow standard-library modules.
3. Explain any command before running it.
4. If a suspicious process starts, ask before cleanup unless the sandbox is disposable.

This is not a fix. It is a smell test. The fix is still to run the session somewhere disposable enough that surprise execution is survivable.

Keep a tiny permission note near risky tasks

When a task involves archives, generated scripts, dependency install steps, or third-party repros, write down the boundary before you ask the agent to work. Keep it short enough that you would actually use it.

Boundary Safer default Why it matters
Filesystem Disposable checkout only A malicious archive can plant import-shadowing files
Secrets No SSH keys, tokens, or cloud creds mounted Prompt injection often aims for exfiltration
Network Egress off unless the task needs it Malware usually wants to phone home
Cleanup Human-approved outside sandbox, automatic inside disposable sandbox Blocked cleanup can preserve a bad process
MCP tools Read-only until the task proves it needs writes External tools expand the blast radius

This is the small, practical piece of the related training topic: do not ask a model to be the only line of defense against an adversarial workspace.

Common questions

  • Did auto mode create the vulnerability?

    No. The underlying issue is the classic risk of executing code from an untrusted workspace, including local files that can shadow trusted imports. Auto mode matters because, in Willison’s account, it allowed the bad process in some runs and then sometimes blocked Claude’s attempt to terminate it.

  • Is Claude Code unsafe to use now?

    No, but unattended use needs a real boundary. Claude Code remains useful for normal development work, especially when commands are reviewed and the repo is trusted. The risky case is adversarial input: unknown archives, hostile issues, external repros, or files designed to manipulate an agent.

  • Why did importing base64 touch struct.py?

    Python modules can import other modules as part of their own setup, and local files can sometimes appear earlier on the import path than the standard library. In this case, the reported trick used a local struct.py so a seemingly normal base64 import could trigger attacker-controlled code.

  • Can hooks or MCP permissions fix this by themselves?

    No. Hooks and MCP permissions can reduce mistakes, create audit points, and block known-dangerous actions, but they are not the same as isolation. The Willison note is a reminder that a classifier or policy layer may lack the context needed during a live compromise.

  • What should I test after reading Willison’s post?

    Test your agent’s behavior on untrusted workspaces inside a disposable sandbox. Start with a harmless import-shadowing drill, then inspect what commands the agent wanted to run, what it was allowed to run, and what it was blocked from doing during cleanup.

Best ways to use this research

  • Best for: Developers who let Claude Code run commands against third-party repros, copied bug reports, or downloaded archives.
  • Best first artifact: A one-page sandbox note that says what is mounted, whether network egress is allowed, and how cleanup should work.
  • Best comparison angle: Compare permission modes by what happens after compromise is detected, not only by what they block before execution.
  • Best caution: Do not convert this into panic. Convert it into a smaller execution environment.

Further reading

Next step

Run the shadow-import drill in a disposable directory, then decide where your next unattended Claude Code session should run. If the input can be adversarial, put it in a sandbox before auto mode ever gets a vote.

One methodology lens

One useful way to read this through our methodology is the Plan step: delegate first-pass decomposition and dependency mapping, review the sequencing and assumptions, and keep ownership of scope and priorities. If that split is still fuzzy, the workflow usually is too.

Related training topics

Related research

Continue through the research archive

Ready to start?

Transform how your team builds software.

Book a 15-minute sync