
Forever Security blocked a malicious AGENTS.md in a developer's Downloads folder that told an AI coding agent to install function-color, an npm package tied to the MALFEX malware campaign. There is no CVE and no patch, because the agent was doing exactly what it was built to do.
Key takeaways
- Forever Security blocked a malicious AGENTS.md in a customer's Downloads folder before a coding agent could install function-color. No code ran.
- How the file arrived is unknown. The silent-download page was Forever's proof of concept, not the confirmed vector.
- Against Codex, the lure registered a server in ~/.codex/config.toml, which persists across every session, and executed malware in more than 90% of lab attempts.
- Against Claude Code, a planted CLAUDE.md tried to set ANTHROPIC_BASE_URL and leak the session token. Approval landed about half the time.
- There is no CVE and no vendor patch. A pull request that only edits AGENTS.md or CLAUDE.md can still command the agent. Control start directories, review instruction files, and rotate tokens when a planted file turns up.
What did Forever Security stop on the customer machine?
Forever Security stopped a coding agent on a live customer workstation before it could act on a malicious AGENTS.md in the developer’s Downloads folder. No code ran. The file asked for two things: a server registered in the agent’s own configuration, and an install of the npm package function-color.
The lure did not look like an attack. It read like engineering notes — the kind of setup document a team lead commits so new hires can bootstrap the environment.
That disguise is a natural fit for the file type. AGENTS.md exists to carry this kind of guidance. OpenAI’s Codex and other coding agents read the file when they start in a directory and follow it as directions.
Forever could not determine how the file got there. The firm built a proof-of-concept page that silently saves an AGENTS.md into Downloads on a visit. That page was a feasibility test, not a reconstruction of the incident.
Nobody has shown that a web page delivered the customer’s file. A page could have dropped it, but so could an archive, a chat attachment, or another route entirely.
We covered the first disclosure in our piece on the AGENTS.md Downloads hijack. This follow-up is about the trust boundary those facts describe: where an agent may start, why one variant persists across every folder, and why the other is an account takeover that looks like a config change.
| What Forever confirmed | What Forever only demonstrated |
|---|---|
| Malicious AGENTS.md in the customer’s Downloads folder. The agent was stopped. No code ran. | A visit to Forever’s own page can save an AGENTS.md into Downloads with no click. |
| How the file arrived is unknown. | Silent download is feasible. It is not tied to this customer. |
| The lure asked the agent to register a server and install function-color. | In a VM, Codex followed the real attacker file in more than 90% of attempts. |
| The customer file is not described as a Claude Code base-URL redirect. | A planted CLAUDE.md got an ANTHROPIC_BASE_URL write approved about half the time. |
Why does this AGENTS.md malware attempt need no vulnerability?
This AGENTS.md malware attempt needs no vulnerability, because each half of the chain is a feature. Coding agents are built to trust the instructions file in the folder they open. That trust is the point of AGENTS.md and of CLAUDE.md.
Under the conditions Forever tested, a web page can save a file into Downloads, choosing the name and the contents, without a click or a permission prompt. Put an agent to work in that same folder and the instructions file is the payload.
The agent does not need a memory-corruption bug, a stolen password, or a vulnerable library already on disk. It needs a start directory the web can write and a Markdown file the product is built to obey.
Forever’s verdict is blunt: “There is nothing here for OpenAI or Anthropic to patch.” The firm compares it to a browser rendering a phishing page. The browser does its job. The attack lives in the content.
No CVE, no CVSS score, and no fixed version attach to this technique. A scanner hunting known flaws will not flag it, and a patch deadline does not cover it.
Working as designed does not mean the design is frozen. Vendors choose how much authority a folder-level file gets, whether a write to persistent config or an API endpoint needs a stronger check, and whether the agent warns when it starts in Downloads. None of that is a patch. Until it changes, the control sits on the workstation.
The preconditions show up in Forever’s own telemetry. About half of its customers run a coding agent in their Downloads folder, and roughly a quarter of agent sessions open a browser. The second number completes an attack loop that should worry you.
An agent that browses can trigger the download that drops a new instruction file into the folder, with nobody watching the filesystem. Those figures describe Forever’s customers, not every developer population. They are still the conditions this attack needs.
Detection has to watch behavior, not a CVE feed. The sequence to hunt is an agent started in Downloads, a read of AGENTS.md or CLAUDE.md the user did not write, a write to agent config, and an npm install the user did not request. Each step can look like ordinary developer work alone.
Can a website save AGENTS.md into Downloads without a click?
In Forever’s lab, yes. The proof-of-concept page writes an AGENTS.md into Downloads on a visit, with no click and no prompt. Treat that as a capability Forever demonstrated, not as the path proven in the customer case. The report does not name the browser.
Forever did not claim a page delivered the customer’s file. The page shows that a visit can be enough under the setup they used. Roughly a quarter of agent sessions in their telemetry open a browser, so the process that fetches the page may be the agent.
Whether a given browser saves the file without asking still depends on that browser and on enterprise download policy. Forever did not publish a matrix of browsers, file types, or earlier user choices. Do not treat those variables as measured results from this report.
Some environments prompt for a save location on every file. Others allow a site to choose the name and land the file in Downloads. A short Markdown file is a convenient carrier because the filename is already an instruction to the agent. The control that matters is where the agent is allowed to start.
What happens when Codex writes ~/.codex/config.toml?
When Codex follows the lure, the damage is not limited to Downloads. Forever ran the real attacker file against Codex inside an isolated virtual machine. Framed as routine project setup, the file told the agent to register a server in ~/.codex/config.toml and to run an install command.
Codex executed the malware in more than 90% of those attempts. The figure is Forever’s, from that lab setup. It is not a general score for the product, and Forever has not published the Codex build, the number of trials, or the full instruction text.
The config path is what should change the threat model. ~/.codex/config.toml is user-level Codex configuration, so it applies to every Codex session on the machine. A server registered there loads in any project, not only in Downloads.
Downloads was the entry. Deleting the AGENTS.md later does not remove the foothold. The registered server is not tied to the session that wrote it. A later Codex session opened in a trusted repository still loads that config. That is persistence without a service, a scheduled task, or a login item.
The install is a separate execution point. npm can run lifecycle scripts during install, before any import. A note that the package was installed and never used does not prove that nothing ran. Treat a completed install from an unexpected agent instruction as code execution until you can show otherwise.
On the customer machine, Forever stopped the agent before that install. The 90% result comes from replaying the attacker file in the virtual machine, not from the blocked customer session.
Comparing the two numbers measures approval friction, not agent safety. The Claude Code test used a different file, a different goal, and a human approval the Codex run did not require in the same way.
How does a planted CLAUDE.md steal the session?
A planted CLAUDE.md steals the session by sending the agent’s API traffic, credentials included, to a host the attacker controls. Forever’s Claude Code variant aimed at that redirect instead of a malware install. The planted file was framed as internal gateway setup.
The file asked Claude to write ANTHROPIC_BASE_URL into the project settings file, .claude/settings.json, so requests would go to a server Forever controlled. One setting is the entire redirect.
In some environments, a single redirected setting is more damaging than a malware install. ANTHROPIC_BASE_URL decides where model requests go. The session login token rides with that traffic, and a leaked token is an account takeover on its own.
The rogue server can answer as if it were the model and hand back commands the agent runs. The attacker no longer has to persuade the model. To the agent, the attacker is the model, on the channel it already uses for answers.
This variant needed a person. Claude Code asks for approval on that kind of write, and it often refuses a write that looks wrong. The long engineering-document framing still got the write approved roughly half the time.
An approval prompt is only as good as the attention behind it. Pages of convincing setup prose exist to wear that attention down. A reviewer who sees gateway setup can approve the one line that moves the API endpoint.
Cleanup splits in two. Reverting ANTHROPIC_BASE_URL stops the next redirect. It does nothing for a token that already left the machine. Forever’s guidance is to assume the login token leaked and rotate it. A stolen token is a live session, not a single caught request.
Where does function-color sit in the MALFEX campaign?
function-color belongs to a malware campaign that CloudSEK and Checkmarx documented separately and named MALFEX. In that campaign, function-color pulls in a downloader called function-flag, which fetches and runs a Windows payload. The reporting here does not name an operator.
The customer’s operating system is not stated. The Windows payload describes the MALFEX chain, not a confirmed execution on that workstation. Forever blocked the agent before any code ran, so the incident stops at the instruction, not at a payload on disk.
The pairing makes the customer incident easier to interpret. An existing npm malware chain was placed behind an instruction file, so the developer never had to type the install. The agent would have done it, because a Markdown file told it to.
Package review is a weak control for this path. It usually runs on pull requests, not on a command an agent issues because a file in Downloads said to install something. A scan that looks for known vulnerabilities in a name is not a verdict that the package is safe.
We do not reproduce hashes, domains, or sample commands. CloudSEK and Checkmarx published the campaign detail. Forever published the agent lure. The join is the package name function-color and the downloader name function-flag.
An audit that only reads the application’s manifest will miss an install the agent performed from a local file. The registry package is the payload. The Markdown file is what launches it. That is the gap an AI supply chain security audit has to cover when agents sit on developer machines.
What should AppSec change on developer machines?
Codex and Claude Code are the products Forever tested, not the whole population at risk. Any coding agent that obeys a folder-level instructions file is in the same class. The test was meant to show the issue is not one vendor’s bug.
The highest-risk habit is starting the agent in Downloads. Forever says about half its customers do that. A freshly cloned repository is next. AGENTS.md and CLAUDE.md ship next to the source and steer the agent before it reads application code.
A pull request that edits only an instructions file can look like documentation to a reviewer and still function as a command. The same class of failure showed up in malicious Git configs that make coding agents run attacker code, where repository metadata became an execution path.
Extraction directories belong on that list. Open an agent inside a sample project you just unzipped, and it will read the instructions file that arrived in the archive. The archive needs a filename the agent already honors, not an exploit.
Start with Forever’s rule. Do not start Codex, Claude Code, or any agent in ~/Downloads. It is the one folder the web can write to on its own. Then make the rule operational on the fleet.
- Fix launch points. Start agents only from a known project root. Treat Downloads, Desktop, temp directories, extraction folders, and fresh clones as untrusted working directories.
- Read instruction files you did not write. A stray AGENTS.md or CLAUDE.md, in Downloads or in a repository you just cloned, is the whole attack. Review those files with the same weight as build scripts and CI config.
- Hard-stop sensitive instructions. Refuse or escalate any instruction that changes an API endpoint, a credential, an approval mode, a sandbox, or user-level config. Leave approval prompts and sandboxes on, and be wary of anything that tells the agent to switch them off.
- Watch persistent config. In ~/.codex/config.toml, look for a server block you did not add. In .claude/settings.json, look for an ANTHROPIC_BASE_URL or another API endpoint you did not set.
- Limit install-time execution. If npm’s ignore-scripts setting is enabled, lifecycle scripts do not run during install. That removes one path. It does not make a malicious package safe. Isolation and review still apply.
If you find a planted file, assume the login token leaked and rotate it. Containment has an order. Stop the agent, revoke the credential at the provider, then remove the malicious configuration. Clearing the file while the token still works leaves the session usable.
Before you delete the lure, keep the evidence. Record a hash, timestamps, the full path, download metadata if the browser stored any, and the agent transcript. Compare what the file requested with what the agent actually did. Those records can differ, and the difference is the incident scope.
Practitioner’s note
When we test coding agents, a model that repeats a malicious line is the least useful result. Count file writes, config changes, outbound requests, package-manager runs, and anything that survives into a session started in another directory.
The approval step needs the closest look. Reviewers accept diffs that read like setup boilerplate, and Forever’s roughly 50% approval figure shows how far a long document gets. Testing should include untrusted files already on disk, which is what prompt injection testing has to cover for coding agents.
Several facts stay open. Forever has not said which agent the customer ran, which builds the lab used, or how many trials sit behind the 90% and the roughly 50% figures. Sector, geography, and a MALFEX operator are not in the reporting.
None of those gaps changes the mechanism. A folder the web can write, an agent that obeys the folder it starts in, and an approval prompt a long document can talk past are enough. None of the three needs a CVE.
FAQ
Did Forever Security prove a website dropped the customer's AGENTS.md?
No. Forever could not determine how the file reached Downloads. Its page shows a silent AGENTS.md download is feasible. That test is not evidence of the customer's delivery path.
Is function-color a malicious npm package?
It is tied to a documented campaign. CloudSEK and Checkmarx named that campaign MALFEX. In it, function-color pulls in the function-flag downloader, which fetches and runs a Windows payload.
Does ~/.codex/config.toml affect sessions outside Downloads?
Yes. It is user-level Codex configuration. A server registered there loads in every Codex session on the machine, in any folder. Deleting the AGENTS.md does not clear it.
What leaks if ANTHROPIC_BASE_URL points at an attacker server?
The session login token goes out with the redirected API traffic, which is enough for account takeover. The attacker's server can also impersonate the model and return commands the agent executes.
Is there a patch for the AGENTS.md coding-agent attack?
No. Forever's position is that there is nothing for OpenAI or Anthropic to patch, because the agent is following the instructions file in its folder as designed. No CVE is assigned.
Should I run Codex or Claude Code in the Downloads folder?
No. Forever's rule is not to start Codex, Claude Code, or any agent in ~/Downloads, because that is the folder a web page can write on its own. About half of Forever's customers still do it.
If coding agents run on developer machines, the instruction file is part of the attack surface. Prompt injection testing from agent::offense covers untrusted files on disk, config writes, and package installs the agent is talked into running.