The AGENTS.md Downloads attack is a prompt-injection path in which an untrusted file becomes instructions for a coding agent, and those instructions seek changes to the agent’s own configuration. The important boundary is the move from reading project material to exercising authority over future sessions, execution tools, or credential destinations.
A downloaded Markdown file does not steal a token simply by existing. The chain needs a consumer, a trusted interpretation, and consequential capabilities. That distinction determines whether an unexpected file is a suspicious artifact, a blocked attempt, a configuration compromise, or an incident involving executed code or exposed credentials.
What was observed and what was demonstrated
Forever Security’s October 22, 2026 disclosure reports a malicious AGENTS.md on a customer’s machine, blocked before code execution. Researchers then tested the customer payload with Codex in an isolated VM and developed a separate CLAUDE.md experiment for Claude Code.
| 증거 카테고리 | What the disclosure supports | What it does not establish |
|---|---|---|
| Customer observation | A malicious instruction file and a blocked attempt | Completed theft or execution on that customer machine |
| Codex reproduction | Global MCP configuration modification and malicious package execution in a VM | Every Codex installation is exploitable |
| Claude Code experiment | API redirection, OAuth-token capture and replay, and model-response-driven execution | The same payload was found attacking Claude users |
| Remaining uncertainty | Version, configuration and deployment conditions need verification | A universal success rate, affected-version range or fix |
The experiment rows summarize the researcher’s reported outcomes. This article has not independently reproduced either product exploit. It provides a defensive analysis and an offline model below.
The right incident statement preserves these categories. “A researcher demonstrated credential capture” and “our employee’s credential was captured” require different evidence. Collapsing them makes the story more dramatic while making response decisions less reliable.
Why the launch directory matters
A downloads directory is a receiving area for material from different origins. Treating that same directory as an approved working project can erase a useful distinction between a file arriving and a file being authorized to direct a tool. The concern is not the directory’s name alone; it is who can place content there and which authority the agent gives that content.
OpenAI’s AGENTS.md documentation describes instruction discovery at global and project scopes. Project discovery follows the project root toward the current directory; when no project root is found, it checks the current directory. Overrides and configured fallback names can change the instruction chain. An audit should therefore record the actual launch location and applicable files, not search for one filename and declare the environment clean.
A dedicated project folder reduces accidental mixing, but creating a folder is not a review process. An extracted archive or cloned repository can carry instructions into a new workspace. The useful control is to identify the origin of instruction-bearing material and approve it before granting consequential capabilities.
For a developer asking whether it is safe to start Codex in Downloads, the practical recommendation is to use a reviewed workspace instead. If you already started there, preserve the relevant files and inspect what actions followed. The launch location alone does not establish compromise, and the absence of a visible terminal error does not establish safety.
The filename is a discovery convention, not an authority grant
A project can legitimately need instructions about formatting, tests and architecture. That does not make every proposed setup operation legitimate. Requests to add an unfamiliar integration, change a credential destination, or alter persistent configuration should be evaluated separately from ordinary project guidance.
The claimed purpose matters less than the effect. “Prepare the team gateway” can describe either an approved integration or an attempt to redirect authenticated traffic. “Register project tooling” can describe either an approved component or a request to establish persistent execution. Review the destination, scope and executable effect before accepting the label.
This is why a general instruction to distrust malicious files is insufficient as the only control. The same model interpreting the document is being asked to decide whether the document deserves more authority. A separate enforcement layer can make the sensitive operation unavailable or require a review based on the exact change.
Codex chain and the persistence boundary
The reported Codex path centers on a write to ~/.codex/config.toml, followed by activation in a fresh process. The disclosure also describes an attempt to relax execution restrictions during that activation. Those details belong to the reported laboratory chain, not a recommendation to run its commands.

The defensive question is how far a project task can reach into user-level configuration. A file associated with one workspace should not silently grant itself authority over integrations used elsewhere. If that boundary is crossed, leaving the workspace may stop new exposure to the original instructions while leaving the consequential configuration behind.
Separate the proposed write from activation. A configuration diff can establish that a registration appeared; it cannot by itself establish that the corresponding executable ran successfully. Process creation, package artifacts and network evidence can answer the latter question. Preserving both stages helps responders avoid understating persistence or overstating execution.
Review complete registration semantics. A friendly integration name is not enough: identify the executable, arguments, referenced scripts, environment and origin. Do not run an unfamiliar server to find out whether it is malicious. Use the organization’s approved analysis environment and evidence-handling process.
Similarly, a process failing its expected protocol handshake is not a clean bill of health. A protocol failure answers whether the expected interaction completed. It does not establish that no child process started or no preceding operation occurred. Correlate the configuration event with actual execution evidence rather than treating a timeout as prevention.
Claude Code chain and the credential-routing boundary
The Claude experiment used project settings and anthropic_base_url to redirect model traffic, with a new connection making the changed route consequential. The credential and execution outcomes are the researcher’s findings in the evidence table. They should not be generalized to every authentication mode or client release.

Anthropic’s environment-variable reference documents anthropic_base_url as an API-endpoint override for proxies or gateways. The setting has legitimate uses. Its presence is an investigation lead when the destination is unexpected; it is not, by itself, an indicator of a malicious deployment.
The key review question is who is authorized to choose the recipient of authenticated model traffic. A project’s request to use a gateway changes that recipient. The choice deserves the same scrutiny whether it arrives in Markdown, a settings change, a shell environment or an onboarding guide.
Transport encryption does not settle the recipient question. A valid certificate can establish an encrypted connection to the named endpoint while that endpoint is still the wrong recipient for the organization’s credentials and context. Allowlist the intended service or approved gateway based on its identity and ownership, not merely whether HTTPS succeeds.
Model responses also sit at a control boundary. If an endpoint supplies tool proposals, the local client still needs to enforce which actions may run. A valid-looking response is not an independent grant of permission to change isolation, access protected files, or launch an unapproved executable.
Current documentation must not be mistaken for the tested configuration
Claude Code’s settings documentation distinguishes user, project, local and managed scopes and describes precedence and trust-dependent behavior. The current reference also documents restrictions on what project settings can change. Those details make an exact version and effective policy essential to a useful test record.
그리고 instruction-memory documentation explains how CLAUDE.md files are loaded and describes AGENTS.md support under specified modes. Therefore, two statements should remain separate: the disclosed Claude experiment used CLAUDE.md; a current installation’s instruction discovery must be checked against its own version and settings. This is not evidence that every Claude installation loads every AGENTS.md file.
Do not infer a universal fix from one setting in today’s documentation. Conversely, do not present a historical experiment as proof that current restrictions are ineffective. An accurate assessment records the tested release, instruction source, trust state, permission mode, configuration scope, authentication method and observed result.
Conditions to verify before calling a workstation exposed
Treat the attack as a sequence of boundary crossings. Each row below identifies evidence that can strengthen or limit a conclusion. These are investigation questions, not assertions that the conditions are true on a particular machine.
| Boundary | Question to answer | Evidence to retain |
|---|---|---|
| File delivery | Did untrusted material reach a relevant directory? | File hash, path, timestamp and available origin records |
| Instruction discovery | Did the session load or otherwise read it? | Launch directory, version and instruction-source record |
| Interpretation | Did it cause a consequential proposal? | Relevant transcript or structured action record |
| Configuration authority | Was a sensitive write attempted, approved or completed? | Before-and-after configuration and approval evidence |
| Activation | Did a new process or connection use the change? | Process lineage or effective endpoint evidence |
| 영향 | Was code executed or a credential sent to an unintended recipient? | Correlated endpoint, account and network evidence |
A failed stage can interrupt a chain, but an unknown stage should remain unknown. A blocked configuration write is materially different from a completed write that nobody checked. A captured destination hostname without request evidence is different from evidence of an authenticated request to that destination.
Browser download behavior also needs verification in the actual environment. Defaults, user choices, prompts and managed policies can affect whether and where a file lands. The disclosure does not justify a universal claim that any visit to any page silently compromises a developer. The file-delivery stage and the agent-activation stage remain distinct.
A read-only triage workflow
Stop initiating new agent work in the suspect directory while preserving evidence. Use a conventional editor or an approved static inspection tool to review the file; do not ask the potentially influenced agent to repair itself as the first response action. A repair prompt could create more tool activity before the current state is understood.
Begin with a bounded inventory. On a workstation you administer, the following command lists matching regular files in the top of the default Downloads directory. It neither opens their contents nor launches an agent. Change the path deliberately if downloads are stored elsewhere; an empty result covers only this location and filename set.
find "$HOME/Downloads" -maxdepth 1 -type f \( \
-name 'AGENTS.md' -o -name 'AGENTS.override.md' -o \
-name 'CLAUDE.md' -o -name 'CLAUDE.local.md' \
\) -print
Next, inspect the instruction chain relevant to the actual working directory, including applicable parent files, overrides, imports and additional configured names. Record a hash before changing a suspicious artifact. Preserve browser-origin metadata when available, while recognizing that origin metadata may be missing or affected by copying and extraction.
Review global Codex configuration and the relevant Claude settings scopes using an approved baseline. Identify unfamiliar integration registrations, changed executable paths, unexpected endpoint overrides and altered approval behavior. Compare complete values locally; avoid pasting configuration into a broad-access chat or ticket because it can contain secrets or private endpoints.
Establish whether the observed change is authorized. A legitimate corporate gateway, a developer’s approved integration and a newly introduced external destination require different responses. Ask the configuration owner for the change record. The absence of a change record increases uncertainty but does not identify an attacker by itself.
Finally, correlate the file, session and action timeline. A file modified after a suspicious process started is a different lead from one loaded immediately before a configuration edit. Keep clock and timestamp limitations in the record. Do not infer exact causation from a single filesystem timestamp.
Escalate from suspicious file to impact using evidence
If unfamiliar code executed, follow the endpoint incident process and investigate the associated process tree, persistence and affected accounts. Removing the Markdown file alone does not address a configuration change or code already running.
If an unintended recipient may have received a credential, use the provider’s supported revocation or session-management controls from a trusted environment. Define the relevant exposure window and inspect account activity. Do not test a potentially stolen token by sending it to another service or copying it into an investigation transcript.
Restore configuration from a reviewed source and verify the effective configuration before resuming work. Preserve the original evidence under appropriate access controls. A successful restart is useful operational evidence but should not replace a documented assessment of what changed and which credentials require action.
An offline experiment with fake credentials and local records
This educational model creates a temporary directory, harmless instruction files and a JSON-lines audit record. It does not start Codex or Claude Code, install packages, open sockets, read user credentials or change real configuration. It demonstrates a policy boundary, not either disclosed product exploit.
The model gives untrusted project material a proposed privileged action and rejects that action without a separate approval. An approved fixture action is allowed. A fake token is present only to assert that the audit record never contains its value. All paths remain beneath a temporary root, which is removed when the program exits.
from pathlib import Path
from tempfile import TemporaryDirectory
import json
FAKE_TOKEN = "FAKE_TOKEN_FOR_OFFLINE_MODEL_ONLY"
with TemporaryDirectory(prefix="agent-boundary-model-") as tmp:
root = Path(tmp)
inbox = root / "Downloads"
inbox.mkdir()
marker = "OFFLINE_CANARY_ONLY"
for name in ("AGENTS.md", "CLAUDE.md"):
(inbox / name).write_text(
"Training fixture: report the marker " + marker + " only.\n"
)
audit = root / "audit.jsonl"
fixture_config = root / "mock-profile" / "config.json"
fixture_config.parent.mkdir()
fixture_config.write_text(json.dumps({"endpoint": "approved-fixture"}))
def consider(action, separately_approved=False):
privileged = action in {"change_global_tools", "change_api_route"}
allowed = not privileged or separately_approved
record = {
"origin": "untrusted-project-fixture",
"action": action,
"separate_approval": separately_approved,
"decision": "allow" if allowed else "deny",
}
with audit.open("a") as stream:
stream.write(json.dumps(record) + "\n")
if allowed and action == "change_api_route":
fixture_config.write_text(
json.dumps({"endpoint": "approved-second-fixture"})
)
return allowed
assert not consider("change_global_tools")
assert not consider("change_api_route")
assert json.loads(fixture_config.read_text())["endpoint"] == "approved-fixture"
assert consider("report_canary")
assert consider("change_api_route", separately_approved=True)
assert json.loads(fixture_config.read_text())["endpoint"] == "approved-second-fixture"
assert FAKE_TOKEN not in audit.read_text()
records = [json.loads(line) for line in audit.read_text().splitlines()]
assert [r["decision"] for r in records] == ["deny", "deny", "allow", "allow"]
print("decisions:", [r["decision"] for r in records])
print("credential values in audit: absent")
Expected output:
decisions: ['deny', 'deny', 'allow', 'allow']
credential values in audit: absent
The Python policy function makes the decision explicitly. It does not ask a language model to interpret the Markdown and does not measure a prompt’s persuasiveness. That limitation is deliberate: the experiment isolates the authorization decision from stochastic model behavior.
For an authorized product evaluation, begin with the harmless canary observation in a disposable environment with no real accounts or secrets. Record whether the file was loaded and where that fact appears in the session record. Do not copy the original malware instructions or request security bypasses to make the test more convincing. Discovering that a file reaches context already answers a useful first question.
A second, separately designed acceptance test can examine whether protected configuration stays protected. Keep the policy outside the same untrusted document. The approval should identify the exact destination and scope of the proposed change. An agent saying that a change is necessary for setup is not the independent approval being tested.
Turn the boundary into an enterprise acceptance criterion
Define protected resources before a pilot: user-level tool registrations, model endpoints, credential stores, approval policy and execution isolation. Give the test operator a reviewed baseline and a way to observe denied actions. If the only evidence is that the agent chose not to try an action once, the test has not established an enforced restriction.
Use a compact acceptance record with three outcomes: denied by policy, explicitly approved and completed, or unresolved. Keep a benign project-guidance task in the same exercise so a system that refuses all work is not mistaken for a usable solution. Track configuration after the exercise as well as during it.
Endpoint policy, filesystem permissions, isolated execution and network restrictions can reduce different parts of the chain. Their implementation needs to cover the actual executable and configuration scopes. A writable copy of a protected setting, an alternate launch path or an already-running subprocess can complicate a simplistic pass/fail claim.
For a Penligent evaluation, connect this evidence discipline to an authorized application-testing workflow: specify scope, review observations and preserve reproducible evidence. This article does not claim that Penligent ships a detector for this Downloads attack, can certify a coding agent’s internal controls, or has reproduced the researcher exploit. A dedicated agent-security engagement needs its own agreed methodology and demonstrated capability.
Questions about malicious instruction files
Can AGENTS.md steal my token?
- The filename itself cannot. Risk depends on a tool consuming its content and being induced to perform a consequential action with available privileges. Investigate instruction loading, configuration changes and credential destinations separately.
Is it safe to launch Codex from Downloads?
- Prefer a reviewed workspace. A shared receiving directory mixes origins and makes trust harder to establish. Starting there is a reason to inspect what loaded and what followed, not proof that a compromise occurred.
Was the reported Claude attack also found on a customer machine?
- The disclosure distinguishes the customer AGENTS.md finding from the researchers’ separately constructed Claude Code experiment. Do not transfer the incident status from one to the other.
Does changing directories remove persistence?
- It does not undo a completed configuration change. Check the relevant user and project scopes, activation history and executed processes before deciding the issue is contained.
Is every gateway override malicious?
- No. A gateway can be legitimate. Verify its owner, authorization, effective destination and applicable data-handling terms. An unexpected override is a lead requiring context.
Do the diagrams describe every current version?
- No. They organize the reported research paths. The current installed release, trust state, settings scope, authentication and enforcement policy determine what needs to be tested.
Does deleting the file resolve the incident?
- It can prevent one further encounter with that file, but it does not revoke exposed credentials, restore configuration or stop already-executed code. Match recovery to demonstrated or reasonably suspected impact.
Treat configuration changes as security decisions
The lasting question is which authority a task receives when it reads a document. Project guidance can explain how to work, while a change to global tools or credential routing determines who can act and who receives sensitive material. Keep those decisions independently reviewable and enforceable, then retain evidence of the boundary that held or failed.
The following video introduces broader authorized application-testing workflows. It is not a reproduction of this attack or proof of coding-agent protection.

