Johann Rehberger published an analysis of prompt injection in Claude Code's auto mode with Opus 5, and Simon Willison picked it up a few days later. The material I have on hand doesn't reproduce the exact mechanism of the bypass —for that you need to read the original post, and I recommend you do— so I'm not going to describe steps I haven't verified. What can be discussed without knowing every detail is the category of the problem.
Why it matters
The signal isn't "a bug showed up in Opus 5." The signal is that auto mode is, by definition, the decision to take the human out of the point where permissions get granted. Prompt injection isn't a one-off vulnerability you patch and close: it's a structural property of any system where the same context mixes your instructions with text you didn't write. A dependency's README, a GitHub issue, the HTML of a page the agent went off to read, the output of a command. All of it comes in as text, and the model has no separate channel to distinguish "this is a legitimate order" from "this is content I'm analyzing."
As long as manual approval sat in the middle, that ambiguity had a shock absorber: you saw the command before it ran. Auto mode removes the shock absorber. I don't say that as a reproach —I use it, it's enormously productive— I say it because it's worth calling it by its name: it's a security architecture decision dressed up as a convenience checkbox.
And this week's context pushes in the same direction. Vercel announced you can now run Claude Managed Agents with the Chat SDK, with the agent loop handled server-side: model, tools, session state and sandboxed web research. GitHub, for its part, extended Copilot code review to pull requests created by bots and removed the 300-file or 20,000-line limit. These are good product news. They also mean more agents reading third-party content, more agents reviewing other agents' output, and fewer human eyes per unit of executed action.
What changes in practice
The first thing I changed in my workflow a while back: an agent's output is untrusted input. If one agent writes a PR and another agent reviews and approves it, the entire chain has no point where anyone validated the content against human intent. That isn't automation, it's a closed loop.
The second is to stop thinking "do I approve this command?" and start thinking "what's the worst this process can do if the model does exactly what the malicious text told it to?" The answer gets bounded with configuration, not with trust:
// .claude/settings.json
// the agent reads and writes in the repo, but reaches
// neither the network nor the environment variables
{
"permissions": {
"allow": ["Read", "Edit", "Bash(npm run test:*)"],
"deny": ["Bash(curl:*)", "Bash(env)", "Read(./.env)"]
}
}
An explicit allowlist is worth more than a long denylist: the denylist enumerates what occurred to you, the allowlist enumerates what the task needs. And if the task needs the network, let it need it inside a container with no credentials mounted, not in your session with the production token sitting in the environment.
Third, and this is the one most people skip: separate the reading role from the writing role. An agent that researches —that opens pages, reads issues, summarizes documentation— is the one most exposed to hostile content, and it's precisely the one that needs execution permissions the least. Running it with the ability to write to the repo and make outbound requests combines the largest input surface with the largest blast radius.
Fourth: no auto-merge on agent-generated PRs, no matter that another agent reviewed them. Automated review is there to cut the noise before it reaches the human, not to replace them.
When NOT to use it
I'm going to be honest in both directions, because the advice "never use auto mode" is as useless as "turn it on and forget about it."
Where auto mode seems reasonable to me: repositories with no secrets, in a disposable container, with the work scoped to files you already know, no outbound network access, and the diff reviewed before committing. There the worst case is losing time, and the savings are real.
Where I wouldn't turn it on today:
- When the agent is going to read content you don't control: public issues, third-party PRs, web pages, new dependencies. That is literally the way in.
- When there are MCP servers connected that touch real systems: production database, ticket tracker, email, deploy. The combination of "reads anything" + "can write to production" has no reasonable mitigation on the prompt side.
- When the repository has credentials in the environment, even staging ones. A leaked token is a leaked token.
- When the pipeline deploys automatically on merge. The blast radius stops being your working tree.
And the inverse tradeoff, which is equally honest: approving every permission by hand doesn't scale and ends in reflex approval, which is worse than not having the prompt at all. If your only defense is your sustained attention on the Enter key, you have no defense. The goal isn't more friction, it's less blast radius.
A limit of this analysis itself: with the material I have I can't tell you whether what was reported is already mitigated, or which versions it applies to. I'm not claiming it either way.
What I'd do today
I'd read Rehberger's full post before any summary —including this one— and then I'd check two concrete things: which MCP servers I have connected in the sessions where I use auto mode, and whether my permission rules are written as an allowlist or as a denylist I've been patching along the way. Then I'd move the research work into a container with no credentials. Not because there's a specific exploit that scares me, but because this class of problem isn't going away: every release that runs more of the loop unsupervised makes the important question always the same one — how much can this break if it obeys the wrong person.