AGENTS.md Downloads Attack: Audit Codex and Claude Code

Inspect downloaded instruction files before starting a coding agent. Check Codex user configuration, Claude Code settings precedence, and evidence of function-color installation. Distinguish the reported attack from lab results, revoke affected credentials, and verify a legitimate gateway without treating user-level settings as a security boundary.

Contents
AGENTS.md Downloads Attack: Audit Codex and Claude Code

Do not start Codex or Claude Code in ~/Downloads or another folder that collects unreviewed files. To check exposure to the AGENTS.md Downloads attack, inspect instruction files and agent configuration before restarting either tool. If you find an unauthorized endpoint or evidence of malicious package installation, stop affected sessions and revoke the relevant credentials.

This workflow covers local Codex and Claude Code, with configuration checked as of 2026-10-28. It produces a list of files to review, a configuration audit, and a decision about whether incident response is needed.

What the Downloads attack demonstrated

The attack combines untrusted instructions with changes to an agent’s own configuration. Markdown does not execute itself; the agent supplies the tools.

Forever Security’s October 22 report describes a blocked installation attempt triggered by a customer’s ~/Downloads/AGENTS.md. How that file arrived remains unknown.

  • Codex reproduction: instructions registered a Model Context Protocol (MCP) tool server in ~/.codex/config.toml, using launchctl and npm to install function-color. A child codex exec used --dangerously-bypass-approvals-and-sandbox.
  • Claude Code reproduction: CLAUDE.md induced an ANTHROPIC_BASE_URL change in .claude/settings.json. Researchers captured an OAuth token, which authenticates the signed-in account, and returned forged Bash calls. A subagent sometimes opened the redirected connection within the same session. The report says that write required human approval.

Reported success exceeded 90% for Codex, reached about 50% for Claude’s configuration change, and reached about one-fifth for Claude’s same-session execution. Most trials used a calculator substitute; the real package ran once in an isolated VM. These are the researchers’ test results, not estimates of your personal risk.

Browser behavior also depends on configuration. Chrome’s documentation describes a configurable download destination, optional save-location prompts, and download notifications. A browser download and a successful agent compromise are separate events.

Current controls matter. Codex 0.165.0 skips project instructions for explicitly untrusted projects. OpenAI also documents protected .codex paths under its default workspace-write policy. Keep those controls enabled; a previously reviewed folder can receive new, unreviewed content.

Run a five-minute first pass

Inspect files from an ordinary terminal and text editor while the agents are stopped. About five minutes is an estimate for one familiar workspace; investigating findings and repairing a host take longer.

1. Locate instruction files before opening an agent

Start with the actual working directory and download destination. In Bash on macOS or Linux, use this filename-only inventory if ripgrep, rg, is installed:

pwd -P
rg --files --hidden --no-ignore \
  -g 'AGENTS.md' -g 'AGENTS.override.md' \
  -g 'CLAUDE.md' -g 'CLAUDE.local.md' \
  -g '**/.claude/settings*.json' \
  -g '**/.codex/config.toml' -g '.mcp.json' \
  -g '!**/.git/**' -g '!**/node_modules/**' \
  "$HOME/Downloads"

Replace the final path if your browser downloads elsewhere. Repeat the scan for a downloaded or cloned project’s directory. Without rg, inspect these names in a file manager with hidden files visible.

The command lists paths without starting an agent or printing configuration values. Resolve missing-directory and permission errors before interpreting an empty result. It does not inspect archives, follow nested symbolic links, or prove that the machine is clean.

Open matches as plain text. Look for instructions to rewrite agent settings, change providers, install unexpected tools, or disable approvals. Review imported or linked instruction files separately.

Also inspect global instructions in your Codex home and ~/.claude/CLAUDE.md. Codex discovers project instructions from the detected project root to the working directory. Without a project root, it checks only the current directory. Include AGENTS.override.md and any configured fallback filenames.

Claude Code also loads ancestor instruction files. Moving into a subfolder of Downloads therefore does not reliably remove the instruction source. Keep the reviewed workspace outside the download tree.

2. Audit Codex configuration across projects

Open ~/.codex/config.toml before launching Codex. This is user-level configuration, so a change can affect that user’s other projects. If you set CODEX_HOME, inspect config.toml there instead.

Also review the profile file selected by your launcher and applicable project .codex/config.toml files. OpenAI’s configuration guide explains which layers load; its advanced guide covers configuration homes and profiles.

SettingWhat to verify
[mcp_servers.<name>]Recognize the server and review its complete command, args, cwd, env, or remote url.
chatgpt_base_urlConfirm any override of the ChatGPT service address was intentional.
openai_base_url, model_provider, and model_providers.<id>.base_urlMatch the API route to the provider you approved.
projects.<path>.trust_levelReview saved trust decisions, especially for broad folders such as Downloads.

MCP connects agents to tools. A local MCP server configuration can launch a process. Check its arguments and destination, not just its friendly name.

An unfamiliar server needs investigation. A generic server name or the presence of npm, npx, or launchctl alone does not establish malware.

As of 2026-10-28, the Codex configuration reference says project-local settings cannot override chatgpt_base_url or provider-routing keys. That restriction does not undo an unauthorized change to user configuration.

3. Audit Claude Code settings and their precedence

Check all settings sources that can supply the endpoint. For a session started at a project root, review these files:

FileScope
~/.claude/settings.jsonYour settings across projects.
.claude/settings.jsonShared settings for this project.
.claude/settings.local.jsonYour local settings for this project.

If you use CLAUDE_CONFIG_DIR, inspect that configuration home for the user file. Ask your administrator about managed settings on a company device.

Inspect env.ANTHROPIC_BASE_URL, HTTP_PROXY, and HTTPS_PROXY. Check which authentication variables are configured without copying their secret values into chat or logs. Also review unexpected hooks and changes to permission rules.

Anthropic documents ANTHROPIC_BASE_URL as an API endpoint override. Its presence is normal for an approved gateway. An unfamiliar hostname, unexplained change, or endpoint supplied by downloaded instructions requires investigation.

Claude Code’s settings precedence puts project-local settings above shared project settings, and both above user settings. In most sessions, a settings-file env value also replaces the same variable inherited from your shell. A user-level endpoint or shell export is therefore not a security lock.

For unexpected MCP integrations, inspect .mcp.json too. Anthropic’s MCP security guidance explains that other scopes and plugins can add servers outside that file.

4. Look for installation evidence

Search package metadata and logs if an agent ran in a suspect directory. From that directory, this Bash command prints matching filenames only:

rg -l --hidden --no-ignore -F 'function-color' \
  -g 'package.json' -g '*lock*' \
  -g 'npm-shrinkwrap.json' -g '*.log' \
  -g '!**/.git/**' \
  .

Review any matches locally. Also inspect /tmp/ptools and relevant npm installation logs if they exist. A project-only search can miss installations elsewhere.

Checkmarx’s package analysis identifies function-color versions 1.0.0 and 1.7.3 as malicious wrappers around function-flag. Its examined downloader targets Windows. Do not infer a particular payload ran merely because a macOS configuration mentions the package.

A mention in an article is different from an installed dependency or installation log. A lockfile alone does not prove that an installation script ran. Installation evidence warrants treating the host as potentially compromised until investigated. Do not install or import the package to test it. An empty search cannot rule out renamed payloads or deleted evidence.

Act on the finding before signing in again

Revoke exposed credentials from a trusted device before reusing the affected configuration. Follow the branch that matches your evidence:

  • Unfamiliar instructions, with no evidence they were used: preserve the file for review and keep it outside agent discovery. Inspect configuration before deciding whether credentials were exposed.
  • An unauthorized endpoint that may have received authenticated requests: assume the affected credential could be exposed. Revoke it and inspect account activity.
  • Evidence that malicious package code ran: isolate the host and involve your security team. Preserve relevant files and logs before cleanup. Removing the Markdown file alone does not remove installed code or repair stolen credentials.

For Claude subscription authentication, use Claude’s account-session controls. Under Settings → Account, revoke affected sessions or use the account-wide logout action. If Claude Code tokens are listed under Settings → Claude Code, remove the affected authorization there. Anthropic states that account-wide logout includes Claude Code and setup-token tokens.

API keys require a separate action. Anthropic’s compromised-key instructions direct you to delete the affected key and create a replacement. Account logout does not revoke API keys.

For OpenAI access, follow its account-compromise instructions: terminate account sessions, delete exposed API keys, review activity, and contact support. Do not assume deleting a local credentials file invalidates a stolen remote session.

Restore reviewed configuration and remove unauthorized startup integrations before authenticating on the machine again. If you cannot establish what ran, keep the host out of normal development work pending investigation.

Keep legitimate gateways under your control

Choose the gateway address yourself and verify where that setting comes from. For personal use, keep the approved endpoint in your user configuration or a shell environment you control. Managed teams should use their approved deployment path.

Treat a project-supplied endpoint as a configuration change to review. It may be legitimate team configuration, but it must not gain approval merely by describing itself as an internal gateway.

For example, BetterToken’s Claude Code instructions use https://bettertoken.ai, without /v1, and your own BetterToken API key. That API access is separate from a Claude subscription. Use the gateway’s own credential; do not supply a subscription OAuth token.

For a deliberate Codex integration, compare the provider block with the Codex custom-provider setup guide. Do not repurpose chatgpt_base_url as a generic model API setting.

After configuration review or completed recovery, a controlled Claude Code connectivity check can exclude project settings and customizations. Run this from an already-reviewed project directory:

claude --safe-mode --setting-sources user --permission-mode default

The CLI reference documents these flags. Safe mode skips customizations such as instruction files, plugins, and MCP servers. Authentication and permissions still operate; user configuration and managed policy still require trust. The default permission mode is labeled Manual.

If your client rejects a flag, check claude --help and its official update instructions before continuing.

Use /status to check loaded settings sources. Then send a small prompt such as Reply with OK. Do not use tools. Expect a response in the terminal. Where provider records are available, match the request time to confirm that request’s route. This consumes normal model usage.

A model naming itself does not verify the endpoint. If the route remains unclear, follow the Claude Code active-provider checks. Stop if configuration changes unexpectedly. This connectivity check does not establish that a host is clean.

Keep downloads separate from daily agent work

Use a reviewed project directory outside your browser’s download destination. For a downloaded CSV, copy only the required input into that workspace after checking it. Moving an entire unreviewed folder also moves its instruction files.

In Chrome, open Settings → Downloads and enable Ask where to save each file before downloading. This adds a decision point; it does not replace inspecting files already saved.

Keep sandbox restrictions and approval controls enabled. Codex’s security documentation distinguishes command sandboxing from MCP connections and client authentication traffic. A read-only command sandbox does not make an unreviewed configuration safe to initialize.

Apply the same review after a fresh clone, an archive extraction, or a change to agent settings. If a task requires running untrusted code, use an isolated environment without your normal development credentials.

Ready to optimize your LLM workflow?

Join thousands of developers building faster, smarter, and more cost-effective AI applications with BetterToken.

Get Started for Free