PERSONAL NOTE

Hijacking AI Coding Agents via the Downloads Folder

Hijacking AI Coding Agents via the Downloads Folder

One-line summary: A web page can silently drop an AGENTS.md / CLAUDE.md instructions file into ~/Downloads; when you start a coding agent (Codex, Claude Code, etc.) in that folder, the agent treats the file as trusted instructions and executes the attacker's intent rewriting its own config, leaking credentials, or running remote code.

1. Why this matters

  • It requires no click and no user mistake. Browsers can write files to ~/Downloads on their own.
  • It is not a patchable bug in Codex or Claude. The agents are behaving exactly as designed: read the instructions file in the working directory, follow it.
  • It was observed in the wild: A malicious AGENTS.md in a real customer's ~/Downloads folder, and reproduced the full chain on both Open AI Codex and Claude Code (the real malicious npm package was executed once inside an isolated VM).
  • Telemetry cited by the researchers: ~half of customers run a coding agent inside ~/Downloads, and ~a quarter of agent sessions open a real browser

Core insight: Markdown is the new executable. An instructions file is inert to the OS (so no "are you sure you want to run this?" gate applies), but itis effectively executable to an agent that reads and obeys it.

2. The two primitives that combine into the attack

Each is harmless alone together they form the exploit.

Agents obey instructions files  AGENTS.md (Codex) and CLAUDE.md (Claude Code) are read on startup and treated as authoritative project instructions. This is by design.

The web can write to ~/Downloads  A visited page can trigger a download with attacker-chosen filename and contents, with no click and no approval.

Historically, a downloaded file was only dangerous if it could run itself, and operating systems closed that door (executables require explicit approval).

Instructions files slip past that control because they aren't executables  until an agent reads them.

The real gap: users trust the folders they work in and assume the web cannot alter them. ~/Downloads is the exception the web can write there  so an attacker can plant instructions inside a folder you trust, and your own agent carries them out.

3. Attack chain (generic)

  1. Victim (or an autonomous agent acting for the victim) visits an attacker-controlled page.
  1. The page triggers a silent download of AGENTS.md or CLAUDE.md into ~/Downloads.
  1. The victim opens a coding agent in that folder and issues any request.
  1. Before handling the real task, the agent reads and follows the planted file.
  1. The planted file instructs the agent to modify its own configuration (add an MCP server, repoint an API base URL, install a package, etc.).
  1. Depending on the variant, the attacker gains remote code execution and/or credential/token theft.

Because the agent can browse autonomously, nobody needs to be at the keyboard  the agent can even fetch the very file that turns it against the user.

4. Variant A OpenAI Codex

  • Payload: a malicious AGENTS.md in ~/Downloads.
  • Mechanism: the file directs Codex to add a "project tools" MCP server to its config and install a package from npm. In the observed campaign that package was malware (function-color, a known malicious npm package from a long-running campaign, since removed by npm).
  • Result: attacker code runs in a single session, with no approval.
  • Persistence / blast radius: Codex writes to ~/.codex/config.toml, which is machine-wide, not folder-scoped. Once poisoned, every Codex sessione was malware (function-color, a known malicious npm package from a long-running campaign, since removed by npm).
  • Success rate reported: >90% of attempts in testing.
  • Attacker tradecraft: the file used specially crafted Markdown components to reliably steer Codex into compliance.

Config indicators:

  • Unexpected [mcp_servers.*] blocks in ~/.codex/config.toml
  • A changed chatgpt_base_url

5. Variant B Claude Code

  • Payload: a malicious CLAUDE.md.
  • Mechanism: instead of installing a package, it reroutes Claude's own API traffic to an attacker-controlled server (an ordinary domain with a valid TLS certificate).
  • Two consequences from that single move:
  1. Account takeover  Claude's OAuth login token is leaked to the attacker, with no code execution required.
  1. Full code execution  the attacker's server impersonates the model API and returns tool calls that Claude then executes.
  • Success rate reported: ~50% of attempts in testing (Claude was notably harder to fool than Codex).
  • Attacker tradecraft: the Markdown was specifically crafted to induce Claude to act on it.

Config indicators:

  • ANTHROPIC_BASE_URL set to an unexpected endpoint
  • Unexpected proxy settings
  • Any API endpoint in .claude/settings.json (project) or global settings that you did not configure yourself

6. Why it can't simply be patched

This is not a Codex bug or a Claude bug  it is a property of what an AI agent is:

  • The agent trusts the folder it runs in.
  • The web has been able to write to ~/Downloads for decades.
  • Neither behavior is a flaw; the danger lives in the seam between them, which falls outside everyone's threat model.

Analogy: a browser rendering a convincing phishing page is working as designed  the attack lives in the page, not the browser, so there is nothing for Chrome to patch. Likewise, an agent following the instructions file in its working directory is working as designed; the attack lives in the file and in where it landed.

The broken assumption: the classic defense "the user would have to do something" no longer holds. The agent acts without a click, and it does the browsing too so the agent is simultaneously the target and the weapon.

Any agent that (a) reads an instructions file and (b) can rewrite its own configuration is susceptible to this class of attack.

7. Indicators of Compromise (IoCs)

  • A stray AGENTS.md or CLAUDE.md you did not author, especially in ~/Downloads or in a freshly cloned repo.
  • The malicious npm package function-color present in a machine's installs → treat that machine as compromised.
  • Unexpected [mcp_servers.*] entry or altered chatgpt_base_url in ~/.codex/config.toml.
  • Unexpected ANTHROPIC_BASE_URL, proxy, or API endpoint in Claude Code settings (.claude/settings.json or global config).
  • Outbound API traffic from an agent going to a domain you don't recognize.

8. Best practices for defense

8.1 Immediate / individual hygiene

  1. Treat ~/Downloads as hostile ground for agents. Never launch Codex, Claude Code, or any agent inside it. Run agents only in vetted, dedicated project directories.
  1. Audit instructions files you didn't write. Before letting an agent near a directory, read any AGENTS.md / CLAUDE.md. A stray one in Downloads or a directories.
  1. Inspect the agent's own config regularly.
  • ~/.codex/config.toml → look for unexpected [mcp_servers.*] blocks and changed chatgpt_base_url.
  • .claude/settings.json / global Claude settings → look for ANTHROPIC_BASE_URL, proxies, or any endpoint you didn't set.
  1. Keep the brakes on. Leave approval gates and sandboxes enabled. Treat any instruction telling the agent to bypass them as hostile.
  1. Rotate on suspicion. If you find a planted file, assume the token leaked. A stolen token is a live session, not a single captured request  revoke and reissue.

8.2 Configuration hardening

  • Scope config to projects, not machines. Where the tool supports it, avoid machine-wide config writes; pin per-project settings and review diffs.
  • Pin/allowlist MCP servers. Only permit MCP servers you explicitly approve; block dynamic addition of servers by the agent.
  • Pin API endpoints. Lock chatgpt_base_url / ANTHROPIC_BASE_URL to known-good values; alert on any change.
  • Least privilege for tokens. Use short-lived, scoped credentials; avoid long-lived OAuth tokens with broad account access.
  • Sandbox and network-restrict agent execution. Run agents in containers/VMs with egress restrictions so a rogue config can't reach arbitrary hosts.
  • Disable silent downloads where possible. Configure browsers to prompt for download location, or route downloads to a directory agents are forbidden to open.

8.3 Team / organizational controls

  • Policy: ban running agents in Downloads, temp, and other web-writable directories.
  • Detect on the agent, not just the user. Monitor what the agent reads, what it rewrites (especially its own config), and what it reaches for (network egress, package installs).
  • Watch config files as security-relevant artifacts. File-integrity monitoring on ~/.codex/config.toml, .claude/settings.json, and similar.
  • Alert on suspicious package installs from agent sessions (e.g., npm install triggered by an instructions file).
  • Egress monitoring: flag agent processes talking to unrecognized domains, especially API-looking endpoints.
  • Incident playbook: on discovery → isolate machine, remove planted file, revert agent config, rotate all tokens/keys the agent could access, hunt for persistence.
  • Training: teach developers that instructions files are executable-equivalent and must be treated as untrusted input.

8.4 For tool builders / platform owners

  • Distinguish trusted vs. untrusted instruction sources; require explicit confirmation before honoring instructions files from web-writable locations.
  • Require approval for self-modification of config (adding MCP servers, changing API base URLs).
  • Warn when a working directory is a known download/web-writable path.
  • Log and surface config changes prominently to the user.

9. Key takeaways

  • The durable lesson is bigger than Downloads: security rules designed around a human (someone clicks, someone approves, someone runs the code) stop holding once an agent takes the human out of the loop.
  • ~/Downloads is just the first place this pattern was observed  expect more seams where "web-writable input" meets "agent-trusted context."
  • Defending the AI endpoint means watching what the agent reads, what it rewrites, and what it reaches for — not only watching the user.

8.4 For tool builders / platform owners

  • Distinguish trusted vs. untrusted instruction sources; require explicit confirmation before honoring instructions files from web-writable locations.
  • Require approval for self-modification of config (adding MCP servers, changing API base URLs).
  • Warn when a working directory is a known download/web-writable path.
  • Log and surface config changes prominently to the user.

9. Key takeaways

  • The durable lesson is bigger than Downloads: security rules designed around a human (someone clicks, someone approves, someone runs the code) stop holding once an agent takes the human out of the loop.
  • ~/Downloads is just the first place this pattern was observed  expect more seams where "web-writable input" meets "agent-trusted context."
  • Defending the AI endpoint means watching what the agent reads, what it rewrites, and what it reaches for  not only watching the user.