On 22 October Forever Security described stopping a coding agent on a customer's machine as it installed function-color, a known malicious npm package, on the instructions of an AGENTS.md in the customer's ~/Downloads that nobody had put there. Their proof of concept is a web page that saves a file with that name into Downloads with no click and no prompt. BleepingComputer tried it on 25 October: Chrome, Edge and Firefox saved the file, only Brave asked.

I planted a harmless AGENTS.md in my own Downloads folder and started both agents from it. Codex 0.164.0 injected the file only when Downloads itself was the working directory. Claude Code 2.1.310 loaded it from there, from a plain subfolder, and from a subfolder with its own git repository, because it collects every AGENTS.md from the working directory up to the filesystem root. A repository you unzip into Downloads inherits the planted file.

Loading was deterministic, obedience was not. Haiku followed the planted instruction in three of six runs, Codex on GPT-6 Astra in one of two. For Claude Code, a claudeMdExcludes glob or --setting-sources user kept the file out, and so does a CLAUDE.md in the project. Nothing is patched, because nothing is broken: both agents are reading instruction files exactly as documented.

What Forever Security found

The incident started as an installation attempt. A customer's coding agent, run from ~/Downloads, tried to add function-color to the machine. The instruction came from an AGENTS.md in that folder, written to look like a routine engineering setup document with a short attack section inside it. How the file got there is still unknown. Forever's own telemetry says about half of their customers run a coding agent inside Downloads, and about a quarter of agent sessions open a real browser.

In an isolated VM they fed the real file to Codex, which added a machine-wide config entry and installed the package in more than 90 percent of attempts. For Claude Code they planted a CLAUDE.md that pointed the API traffic at a server they controlled, which would hand over the OAuth token. Claude followed it about half the time, and in the same-session variant ran code about one time in five. Their conclusion, quoted by BleepingComputer: "There is nothing here for OpenAI or Anthropic to patch."

The browser half

Chrome's defaults do the delivery. Files go to ~/Downloads and the "Ask where to save each file before downloading" switch is off until you turn it on. I opened a local page in a fresh profile of Chrome 155 whose only script creates a blob, names it AGENTS.md and clicks a generated link. The page had no buttons and I clicked nothing. A 67-byte AGENTS.md appeared in my Downloads folder. One caveat: the page was opened through the DevTools protocol and reported user activation as true, so the no-gesture half of the claim is Forever's and BleepingComputer's, not mine.

Which folders each agent reads

Claude Code's documentation says it reads, at session start, "every AGENTS.md and .claude/AGENTS.md in your working directory and the directories above it", as long as no CLAUDE.md sits in the working directory or above it. I ran claude -p with Haiku and a debug log from four places, with the canary file in ~/Downloads:

  • From ~/Downloads: loaded.
  • From ~/Downloads/project, an empty folder with one text file: loaded.
  • From the same folder after git init: loaded. The debug line reads AGENTS.md, .claude/AGENTS.md found 1 of 4 directories, and the four are the project, Downloads, my home directory and the root. A git boundary does not stop the walk.
  • From the same folder with its own AGENTS.md: both loaded, and Haiku quoted both canary tokens.

The same walk means an AGENTS.md in your home directory loads into every project under it. A project CLAUDE.md turns the whole mechanism off: with one present, the debug log showed the project's CLAUDE.md and my user CLAUDE.md, and the Downloads file was not read. The InstructionsLoaded hook fired for those two CLAUDE.md files in every run and never once for an AGENTS.md, which is what I found when AGENTS.md support shipped and is still true on 2.1.310. A -p run also shows no workspace trust dialog, and the docs say trust for the home directory itself is never written to disk.

Codex's documentation says instruction discovery "starts at the project root", which is "typically the Git root", and that "If Codex cannot find a project root, it only checks the current directory." I ran codex exec with a read-only sandbox from the same three places and read the session rollouts afterwards. From ~/Downloads the rollout contains the block # AGENTS.md instructions for /Users/marcokotrotsos/Downloads with the canary text inside. From the subfolder, with or without a git repository, the rollout has no trace of it. Downloads is not in my trusted projects list, and Codex loaded the file anyway, which fits the docs: an untrusted folder disables project-local configuration under .codex/, not AGENTS.md.

Loading is reliable, following is not

With the instruction "begin your reply with this token", Haiku complied in three of six runs where the file had loaded, and Codex on GPT-6 Astra in zero of one. When I instead asked each agent what token its instructions mentioned, Haiku answered correctly four times out of four and Codex once out of once, prefixing its answer with the token it had ignored a minute earlier. That is the same shape as Forever's numbers: 90 percent for Codex with their real file, 50 and 20 percent for the Claude Code variants. A planted instruction file is a prompt injection with a good seat, and the model's judgment is the control that actually decides.

The permission layer is the backstop. A claude -p run starts in Manual mode, where a shell command needs an allow rule, a hook or a --permission-prompt-tool, so a planted npm install is denied. In auto mode the classifier decides, and its documented allow list includes "installing dependencies declared in your lock files or manifests", which is a sentence worth reading twice if the agent can also edit the manifest. Codex in read-only mode cannot write the config entry Forever saw; in danger-full-access, which is what my own config sets, it can.

What to do

Check now. ls ~/Downloads/AGENTS.md ~/Downloads/CLAUDE.md ~/AGENTS.md ~/CLAUDE.md should return four errors.

For Claude Code, add a claudeMdExcludes entry to ~/.claude/settings.json. Both an absolute path and the glob **/Downloads/AGENTS.md kept the file out in my runs; the debug log showed no load and Haiku reported no token. Add a line for your home directory's AGENTS.md while you are there. For -p and CI runs, pass --setting-sources user: the debug log then reads project memory is off and nothing from the working directory or above it loads. Setting Project instructions to claude-md under pluginConfigs had the same effect, at the cost of every legitimate AGENTS.md too.

For Codex, the planted file matters when Downloads is the working directory or the git root. Read ~/.codex/config.toml for entries you did not write, since the config change Forever saw was machine-wide, and treat function-color in any lockfile as the indicator of compromise they named.

In Chrome, turn on "Ask where to save each file before downloading". It is the one setting that stops the delivery rather than the execution.

And the advice both vendors gave Forever, with one amendment: start agents in the project folder, not in Downloads, not in your home directory. With Claude Code, not in a folder inside those either, unless the project carries its own CLAUDE.md.