Yaamlabs

AI security

A planted AGENTS.md in Downloads can hijack coding agents

A file in a Downloads folder told OpenAI Codex to install npm malware. How the Codex and Claude Code variants work, and what to check on dev machines.

Researchers at Forever Security found an AGENTS.md file in the Downloads folder of a customer's computer that told OpenAI's Codex to install function-color, a malicious npm package. The developer had started the agent in Downloads, so Codex read the file as project guidance and began the install before Forever stopped it. In a write-up published on October 22, the researchers reproduced the attack against Codex and built a matching CLAUDE.md attack against Anthropic's Claude Code.

This affects anyone who runs Codex, Claude Code or a similar command-line coding agent from ~/Downloads or a broad folder such as their home directory. Forever says about half of its customers run a coding agent in Downloads. There is no CVE and no patch coming: the agents did what they are built to do, which is follow the instruction file in the folder they start in.

How it works

AGENTS.md and CLAUDE.md are plain Markdown files that tell a coding agent how a project is built: which commands to run, which conventions to follow. The agent loads the file from its working directory automatically and treats it as guidance from the project owner. The file contains no code, so antivirus has nothing to flag. What it contains are requests the agent carries out with the permissions it already has.

The planted file was about 13 KB of ordinary-looking engineering notes, with the attack framed as routine setup in one section. It asked Codex to add a server entry to ~/.codex/config.toml, the user-wide configuration file. A server listed there is an MCP (Model Context Protocol) server: a helper program Codex launches when a session starts. The entry's command installed function-color. The file also had Codex run a nested codex exec --dangerously-bypass-approvals-and-sandbox session, which turns off both the approval prompts and the sandbox that normally blocks network access. Because the config is global, the server keeps loading in every later Codex session on the machine, whatever folder the developer is in.

function-color belongs to the MALFEX campaign that Checkmarx documented, which we covered in our MALFEX post. The package has no payload of its own and pulls in function-flag, a downloader that fetches and runs a Windows payload. npm has since removed it.

The Claude Code variant goes after the login rather than the machine. A planted CLAUDE.md, framed as gateway setup, asks Claude to write ANTHROPIC_BASE_URL into .claude/settings.json, which changes where Claude Code sends its API requests. Claude Code asks for approval before that write and often refuses ones that look wrong; the long, mundane framing got it approved about half the time. From the first request of the next session, the traffic and the OAuth login token go to the attacker's server. The researchers replayed a captured token to take over the account, and their server answered as if it were the model, returning tool calls that the client executed. In about a fifth of tests this happened in the same session, because the file also asked Claude to start a helper subagent, and the subagent opened a fresh connection through the new address.

Reports describe the Claude figure differently. Forever's write-up, Help Net Security and CSO Online tie the roughly 50% to the settings write; BleepingComputer ties it to code execution through the attacker's server. All of the success rates come from Forever's own tests, and most of the Codex runs used a harmless stand-in instead of the real package.

How the file got there

Forever could not establish how the file reached the customer's Downloads folder. The researchers built a proof-of-concept page that saves an AGENTS.md into Downloads with no click and no approval prompt. BleepingComputer tried the page: Chrome, Edge and Firefox saved the file with only a download notification, while Brave asked the user first.

Two conditions have to line up: the file lands in Downloads, and someone starts an agent there. Forever's telemetry suggests the second is common. Besides the half of customers running agents in Downloads, about a quarter of agent sessions open a real browser, so an agent browsing on the developer's behalf could fetch the file itself.

What to do

  1. Start agents from the project root: cd ~/code/<project> and launch from there, never from ~/Downloads or ~. A narrow working directory means the only instruction files the agent loads are ones in the repository.
  2. Read any AGENTS.md or CLAUDE.md you did not write before an agent acts on it, including in repositories you have just cloned. The attack was one section of a long file, so read past the first screen. Claude Code applies most env values from a project settings file only after you trust the folder; if the trust prompt appears in a folder you did not expect to work in, answer no.
  3. Keep approvals and the sandbox on. If an agent asks to run codex exec --dangerously-bypass-approvals-and-sandbox, add an MCP server or change an API address during project setup, deny it and stop the session.
  4. In Chrome, Edge and Firefox, turn on the setting that asks where to save each download, or point downloads at a folder nobody runs tools in.
  5. For managed fleets: Claude Code's managed settings, deployed by an organisation through managed-settings.json, MDM or the claude.ai admin console, take precedence over any project settings file, so a value set there cannot be changed by a planted .claude/settings.json.

To check a developer machine on macOS or Linux, these commands cover the four places in the graphic below. Review every hit by hand:

find ~/Downloads -maxdepth 2 \( -name AGENTS.md -o -name CLAUDE.md -o -name .claude \)
ls -la ~/AGENTS.md ~/CLAUDE.md ~/.claude/settings.json 2>/dev/null
grep -n -A4 '^\[mcp_servers' ~/.codex/config.toml
grep -rn 'BASE_URL\|proxy' ~/.codex/config.toml ~/.claude/settings.json ~/Downloads/.claude 2>/dev/null
grep -rl 'function-color\|function-flag' ~/.npm/_cacache/index-v5 ~/.npm/_logs 2>/dev/null

On Windows, the npm cache and logs live under %LocalAppData%\npm-cache, and the payload function-flag fetches only runs on Windows.

If you find a planted file, delete it along with any server entry or base URL it added. Assume the agent's login token leaked: sign out (/logout in Claude Code, codex logout for Codex) and sign in again, and revoke any API key those sessions used. If function-color was installed, treat the machine as compromised and follow the clean-up steps in our MALFEX post.

Instruction files are configuration

Teams already review package.json scripts and CI files because they decide what runs. AGENTS.md and CLAUDE.md now do the same job, with less scrutiny, and an agent with shell access will act on them. Give them code owners in repositories, and add the user-level agent configs (~/.codex/config.toml, ~/.claude/settings.json) to whatever file-integrity checks already watch developer machines.

If you want a second look at how your developers run AI agents, our AI-native systems and safeguarding and hardening work covers agent permissions, settings and egress. Open the chat and Yaali, our AI agent, will pass your question to an engineer.


Sources: Forever Security, BleepingComputer, Help Net Security, CSO Online, The Hacker News, Checkmarx, Claude Code settings documentation.

Back to the blog, or read this post on the full site.