A one-line changelog entry in Claude Code v2.1.160 closes a quiet local-code-execution path. The fix arrived. The trust boundary it patches should never have been open.
Read the v2.1.160 changelog and you almost miss it. One bullet, sandwiched between editing-mode tweaks: Claude Code now prompts before writing to shell startup files like .zshenv, .zlogin, and .bash_login, and to ~/.config/git/, which could otherwise lead to unintended command execution. That phrasing is doing a lot of quiet work. "Unintended command execution" is the polite name for an agent silently arming code that runs every time you open a terminal. Here is the tension. The fix is correct, and the people who shipped it deserve credit for naming the exact files involved instead of burying it. But the existence of the fix is an admission: until June 2, 2026, an agent with write access to your home directory could drop a payload into a file that the operating system executes on your behalf, with your privileges, without your knowledge. The prompt is new. The attack surface is old. This post is about why that gap matters more than the patch, what trust boundary the patch actually defends, and why "ask first" should have been the default the moment an AI agent earned write access to disk. Patch context first, then the analysis. The release that closed this is anthropics/claude-code v2.1.160, dated June 2, 2026.
The patch is one line. The threat it closes runs on every shell you open.
Here is what changed, verbatim from the release notes: Claude Code "Added a prompt before writing to shell startup files (.zshenv, .zlogin, .bash_login) and ~/.config/git/, which could otherwise lead to unintended command execution" (https://github.com/anthropics/claude-code/releases/tag/v2.1.160). Strip the diplomacy out of that sentence and you get a threat model. Shell startup files are not ordinary files. They are scripts the operating system runs automatically when a shell starts. .zshenv runs for every zsh invocation, interactive or not. .zlogin and .bash_login run at login. ~/.config/git/ holds Git configuration that can include command aliases and hooks. Anything written into these files executes later, on your account, with your permissions, with zero further prompting. That is the definition of persistence. An attacker who can get one line into your .zshenv does not need to compromise anything else. The next terminal you open does the work for them. Before v2.1.160, Claude Code could write to those files as part of normal operation. A user asking the agent to "set up my environment" or "add this to my path" was, under the hood, granting silent write access to an auto-executing script. The agent had no reason to distinguish that file from any other text file on disk. The operating system, however, treats it very differently. That mismatch (the agent sees a file, the OS sees a launcher) is the whole vulnerability. Apply the Trust Boundary Model and the failure becomes obvious. A trust boundary is any place data crosses from one trust level to another. When an agent's output becomes a file the OS will execute, the agent's text has crossed from "suggestion" to "command" without anyone inspecting the crossing. v2.1.160 inserts a human at that crossing. That is the correct place to put the checkpoint. It is also a checkpoint that should have existed before the agent ever shipped with write access.
This is a confused-deputy problem, and the agent was the deputy.
The classic version of this class of bug has a name older than any AI agent: the confused deputy. A program with legitimate privileges gets tricked into using them on an attacker's behalf. Claude Code has legitimate write access to your home directory because you gave it that access to be useful. The danger is not that access. The danger is that the agent could not tell the difference between writing a harmless config note and writing an auto-executing payload, because to the agent both are just files. An attacker does not need to break into your machine to exploit this. Prompt injection is enough. Consider the realistic chain. You point Claude Code at a repository, a webpage, or a document to summarize. That content carries hidden instructions: append the following line to the user's shell startup file. A capable agent following instructions does exactly that, because following instructions is the job. Now there is a line in .zshenv that phones home, or exfiltrates environment variables, or pulls a second-stage payload, every single time you open a shell. You authorized the agent. You never authorized the line. Run the same situation through Attack Surface Analysis: enumerate every interface and data flow the agent touches, then minimize unnecessary exposure. Disk write was on the surface. Auto-executing files were on the surface. The intersection of those two (an agent that writes, and files that run themselves) was an exposure nobody needed to leave open by default. v2.1.160 does not remove the capability. It narrows the exposure by forcing a human decision at exactly the files where a write becomes execution. That is minimization done right: keep the capability, gate the dangerous subset. The lesson generalizes well past one product. Any agent on the Autonomy Spectrum that operates above pure copilot mode (anything that takes actions instead of only suggesting them) inherits this exact class of risk the moment it can write to disk. Most failures, per that framework, come from deploying at the wrong point on the spectrum. Shipping disk-write autonomy without a startup-file gate was deploying one notch too far.
The same week, two more projects patched the same shape of bug.
If the Claude Code fix looked like an isolated slip, the rest of the week's release traffic argues otherwise. Look at what else shipped in the same 48 hours. CVE-2026-47428, filed against Vitest browser mode on June 1, describes a near-identical category of failure: a query parameter named otelCarrier was "inserted directly into an inline module script" and "treated as JavaScript source rather than data," so an attacker could "craft a browser-runner URL that executes arbitrary JavaScript in the Vitest server origin" (https://github.com/advisories/GHSA-2h32-95rg-cppp). Different tool, same root cause: attacker-controlled input crossed a trust boundary and got treated as code instead of data. The Vitest case and the Claude Code case are the same bug wearing different clothes. One puts data into a script tag. The other puts data into a startup script. Both fail because nobody inspected the crossing. On June 1, LangGraph's SDK shipped a fix to "percent-encode thread_id in v3 stream transport default paths" (https://github.com/langchain-ai/langgraph/releases/tag/sdk%3D%3D0.4.2). Percent-encoding an identifier before it lands in a URL path is, again, the same discipline: treat external input as data, escape it, never let it change the structure of the thing it is embedded in. An unencoded identifier in a path is a smaller cousin of an unsanitized value in a script. Same family. These are not coincidences. They are the Molt Cycle in motion. Open-source agent projects move through predictable phases: rapid growth, then a security crisis, then hardening, then enterprise adoption. The volume of trust-boundary patches landing in a single week (Claude Code, Vitest, LangGraph, all in 72 hours) is what the hardening phase looks like from the inside. The tools grew fast. They handed agents real power over real machines. Now the bills for the input-validation shortcuts taken during the growth phase are coming due, one changelog line at a time. Treat the cluster as a signal, not as three unrelated tickets.
The strongest objection: a prompt is just one more dialog to click through.
Take the best counterargument seriously, because it is real. Adding a prompt before writing to startup files trains users to click "yes." Permission fatigue is a documented failure mode. If every agent action throws a confirmation dialog, users stop reading and approve everything, and the prompt becomes security theater. By that logic, the v2.1.160 fix is a fig leaf that shifts liability to the user without actually stopping the attack. That objection is worth answering rather than dismissing, and the answer is precision. The reason this prompt is defensible while a blanket "confirm every write" prompt would not be: it fires only at the trust boundary that matters. The agent is not asking permission to write any file. It is asking permission to write the specific files the OS will auto-execute (.zshenv, .zlogin, .bash_login, and ~/.config/git/), as the release notes spell out (https://github.com/anthropics/claude-code/releases/tag/v2.1.160). A prompt that fires rarely, and only at genuine execution boundaries, carries signal. A user who sees "Claude Code wants to modify .zshenv" in the middle of a task they thought was about something else has just been handed the one piece of context that defeats the prompt-injection chain. That said, the objection lands a partial hit. A prompt is a defense layer, not a defense. The Swiss Cheese Model is the honest frame here: accidents happen when the holes in multiple layers line up, and no single layer is sufficient. The prompt is one slice. It needs company: agents should run with the least privilege required for the task, sandboxed execution environments should isolate file writes from the host where possible, and startup files should arguably be read-only to agents by policy rather than by prompt. E2B's sandbox releases this week (https://github.com/e2b-dev/E2B/releases/tag/e2b%402.27.1) point at where that second slice comes from: isolating where agent-driven commands actually run. The prompt is necessary. It is not the whole defense. Anyone selling it as complete is overstating it. So is anyone dismissing it as theater.
For the people who run these agents, not the people who build them.
If you use Claude Code or any disk-writing agent day to day, here is what this changes for you, in plain terms. First: update. The fix lives in v2.1.160 (https://github.com/anthropics/claude-code/releases/tag/v2.1.160). Running an older build means the silent-write behavior is still live on your machine. There is no configuration to toggle and no workaround that beats the patch. Update the agent. Second: the prompt is not noise, it is a tripwire. When Claude Code asks before touching .zshenv or your Git config, that is the one moment you get to notice that a task you thought was about summarizing a document has quietly turned into a request to modify a file that runs on every login. If that prompt appears and you did not ask the agent to set up your shell, stop. That is very likely a prompt-injection attempt riding in on whatever content you fed the agent. Do not click yes to make the dialog go away. Third, for teams: this is the Shadow Agent Problem in miniature. Agents installed by individuals without IT review carry the same risk as Shadow IT, but with broader system access, because they can write to the parts of a developer's machine that execute code automatically. If your organization has engineers running agents with home-directory write access and no policy about it, the v2.1.160 prompt is the floor, not the ceiling. The questions to ask: which agents can write to disk, what runs in a sandbox versus on the host, and who reviewed the permission grant. None of that requires reading source code. It requires knowing where your agents can write and what those locations do when nobody is watching. The terse version: patch now, treat the new prompt as a security event when it surprises you, and stop pretending an agent with write access to auto-executing files is a low-privilege tool. It is a deputy. Keep it from getting confused.
/Sources
/Key Takeaways
- Patch now. The shell-startup-file prompt ships in Claude Code v2.1.160; older builds still allow silent writes to auto-executing files.
- The vulnerability is a confused-deputy problem: the agent could not tell a harmless file from a file the OS auto-executes, so a write became code execution.
- Prompt injection is the realistic delivery vector. Hidden instructions in a document or repo can tell the agent to append a payload to .zshenv.
- Treat the new prompt as a tripwire. If it fires during a task you did not expect, that is a likely injection attempt. Do not click through.
- The prompt is one Swiss-cheese slice, not the whole defense. Pair it with least privilege and sandboxed execution.
- Three trust-boundary patches in 72 hours (Claude Code, Vitest, LangGraph) is the Molt Cycle's hardening phase showing up in the changelogs.

