GenAI Agent Instruction File Written to Downloads

Detects creation or change of an AI coding-agent instruction file (agents.md or claude.md) in a user Downloads folder by a browser or an archive tool. A web page can save AGENTS.md or CLAUDE.md into Downloads without a click, and opening an archive can extract the same files there. Codex and Claude Code treat those files as trusted project instructions, which can lead them to rewrite their own configuration, install a package, or leak a login token.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2026/10/27"
  3integration = ["endpoint"]
  4maturity = "production"
  5updated_date = "2026/10/31"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10Detects creation or change of an AI coding-agent instruction file (agents.md or claude.md) in a user Downloads
 11folder by a browser or an archive tool. A web page can save AGENTS.md or CLAUDE.md into Downloads without a click,
 12and opening an archive can extract the same files there. Codex and Claude Code treat those files as trusted project
 13instructions, which can lead them to rewrite their own configuration, install a package, or leak a login token.
 14"""
 15from = "now-9m"
 16language = "esql"
 17license = "Elastic License v2"
 18name = "GenAI Agent Instruction File Written to Downloads"
 19note = """## Triage and analysis
 20
 21### Investigating GenAI Agent Instruction File Written to Downloads
 22
 23`AGENTS.md` and `CLAUDE.md` are instruction files that coding agents such as OpenAI Codex and Claude Code read when
 24a session starts in that folder and then follow. Downloads is a folder a browser can write to on its own, and it is
 25also where archive tools extract files the user opened. A planted instruction file can tell the agent to register a
 26malicious MCP server, install a package, or point its API traffic at an attacker-controlled gateway.
 27
 28### Possible investigation steps
 29
 30- Open `file.path` and read the file. Look for instructions that edit agent config (`~/.codex/config.toml`,
 31  `.claude/settings.json`, `mcp.json`), register an MCP server, run `npx` or `npm install`, or set
 32  `ANTHROPIC_BASE_URL` or a similar API base URL.
 33- Review `process.name` and `process.executable`. A browser or browser helper means the file was saved from the web.
 34  An archive tool (`7z`, `WinRAR`, `tar`, `unzip`, Archive Utility) means it was extracted from a download.
 35- On the same host and user, look for a preceding download of a zip, rar, or 7z into the same Downloads folder, and
 36  for follow-on writes to `.codex`, `.claude`, or other GenAI config paths.
 37- Check whether Codex, Claude, or another agent was later started with that Downloads folder as its workspace, and
 38  whether it spawned `npm`, `npx`, `node`, or a shell afterward.
 39- If the file is malicious, hunt the same filename and content hash on other hosts.
 40
 41### False positive analysis
 42
 43- Cloning or downloading a legitimate repository into Downloads extracts a real `AGENTS.md` or `CLAUDE.md`. Confirm
 44  the archive or URL and the file contents before excluding.
 45- Saving those files from a browser while working on an agent project in Downloads is expected. Scope exceptions to
 46  a known path, user, or parent archive, not to the filename alone.
 47
 48### Response and remediation
 49
 50- Quarantine the instruction file and any archive it came from. Collect the hash and the download URL if present.
 51- If an agent already consumed the file, review `~/.codex/config.toml`, `.claude/settings.json`, and other MCP
 52  config for new servers or API base URLs, and remove unauthorized entries.
 53- Rotate agent login tokens and any credentials the session could have read. Remove packages the agent installed
 54  as part of the instructions, such as an unexpected npm package.
 55"""
 56references = [
 57    "https://forever.security/blog/hijacking-ai-agents-via-downloads-folder",
 58]
 59risk_score = 47
 60rule_id = "c6c790fe-2bfa-45fa-b3c5-6b702e66bbea"
 61setup = """## Setup
 62
 63This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.
 64
 65Setup instructions: https://ela.st/install-elastic-defend
 66"""
 67severity = "medium"
 68tags = [
 69    "Domain: Endpoint",
 70    "Domain: GenAI",
 71    "Mitre Atlas: AML.T0051",
 72    "Mitre Atlas: AML.T0093",
 73    "OS: Linux",
 74    "OS: Windows",
 75    "OS: macOS",
 76    "Use Case: Threat Detection",
 77    "Tactic: Initial Access",
 78    "Tactic: Execution",
 79    "Data Source: Elastic Defend",
 80    "Resources: Investigation Guide",
 81    "Threat: Unauthorized AI Usage",
 82    "Rule Type: ES|QL",
 83    "Platform: Windows",
 84    "Platform: Linux",
 85    "Platform: macOS",
 86]
 87timestamp_override = "event.ingested"
 88type = "esql"
 89
 90query = '''
 91FROM logs-endpoint.events.file-* METADATA _id, _version, _index
 92| WHERE event.type IN ("creation", "change")
 93  AND TO_LOWER(file.name) IN ("agents.md", "claude.md")
 94  AND (
 95    file.path LIKE "/Users/*/Downloads/*"
 96    OR file.path LIKE "/home/*/Downloads/*"
 97    OR file.path LIKE """C:\\Users\\*\\Downloads\\*"""
 98  )
 99  AND (
100    TO_LOWER(process.name) IN (
101      "google chrome", "chrome.exe", "chrome", "chromium", "chromium-browser", "google-chrome",
102      "microsoft edge", "msedge.exe", "microsoft-edge",
103      "firefox", "firefox.exe",
104      "safari",
105      "brave browser", "brave.exe", "brave", "brave-browser",
106      "opera", "opera.exe",
107      "vivaldi", "vivaldi.exe",
108      "explorer.exe",
109      "com.apple.webkit.networking",
110      "7z.exe", "7zg.exe", "7zfm.exe", "7z", "7zz",
111      "winrar.exe", "rar.exe", "unrar.exe", "rar", "unrar",
112      "winzip.exe", "winzip64.exe",
113      "bandizip.exe", "peazip.exe",
114      "tar.exe", "tar", "bsdtar",
115      "unzip.exe", "unzip", "unar", "ditto",
116      "archive utility", "bomarchivehelper",
117      "the unarchiver", "keka",
118      "file-roller", "ark"
119    )
120    OR TO_LOWER(process.name) LIKE (
121      "google chrome helper*",
122      "microsoft edge helper*",
123      "brave browser helper*",
124      "opera helper*",
125      "vivaldi helper*"
126    )
127  )
128| KEEP
129    _id,
130    _version,
131    _index,
132    data_stream.namespace,
133    @timestamp,
134    host.name,
135    host.id,
136    agent.id,
137    user.name,
138    user.domain,
139    event.type,
140    event.action,
141    file.name,
142    file.path,
143    process.name,
144    process.executable,
145    process.entity_id
146'''
147
148
149[[rule.threat]]
150framework = "MITRE ATT&CK"
151
152[[rule.threat.technique]]
153id = "T1189"
154name = "Drive-by Compromise"
155reference = "https://attack.mitre.org/techniques/T1189/"
156
157[rule.threat.tactic]
158id = "TA0001"
159name = "Initial Access"
160reference = "https://attack.mitre.org/tactics/TA0001/"
161
162[[rule.threat]]
163framework = "MITRE ATT&CK"
164
165[[rule.threat.technique]]
166id = "T1204"
167name = "User Execution"
168reference = "https://attack.mitre.org/techniques/T1204/"
169
170[[rule.threat.technique.subtechnique]]
171id = "T1204.002"
172name = "Malicious File"
173reference = "https://attack.mitre.org/techniques/T1204/002/"
174
175[rule.threat.tactic]
176id = "TA0002"
177name = "Execution"
178reference = "https://attack.mitre.org/tactics/TA0002/"
179
180[[rule.threat_mappings]]
181framework = "MITRE ATLAS"
182version = "2026.09"
183[[rule.threat_mappings.threat]]
184framework = "MITRE ATLAS"
185[[rule.threat_mappings.threat.technique]]
186id = "AML.T0051"
187name = "LLM Prompt Injection"
188reference = "https://atlas.mitre.org/techniques/AML.T0051/"
189
190
191[rule.threat_mappings.threat.tactic]
192id = "AML.TA0005"
193name = "Execution"
194reference = "https://atlas.mitre.org/tactics/AML.TA0005/"
195[[rule.threat_mappings.threat]]
196framework = "MITRE ATLAS"
197[[rule.threat_mappings.threat.technique]]
198id = "AML.T0093"
199name = "Prompt Infiltration via Public-Facing Application"
200reference = "https://atlas.mitre.org/techniques/AML.T0093/"
201
202
203[rule.threat_mappings.threat.tactic]
204id = "AML.TA0004"
205name = "Initial Access"
206reference = "https://atlas.mitre.org/tactics/AML.TA0004/"
207
208[rule.investigation_fields]
209field_names = [
210    "host.name",
211    "user.name",
212    "file.name",
213    "file.path",
214    "process.name",
215    "process.executable",
216]

Triage and analysis

Investigating GenAI Agent Instruction File Written to Downloads

AGENTS.md and CLAUDE.md are instruction files that coding agents such as OpenAI Codex and Claude Code read when a session starts in that folder and then follow. Downloads is a folder a browser can write to on its own, and it is also where archive tools extract files the user opened. A planted instruction file can tell the agent to register a malicious MCP server, install a package, or point its API traffic at an attacker-controlled gateway.

Possible investigation steps

  • Open file.path and read the file. Look for instructions that edit agent config (~/.codex/config.toml, .claude/settings.json, mcp.json), register an MCP server, run npx or npm install, or set ANTHROPIC_BASE_URL or a similar API base URL.
  • Review process.name and process.executable. A browser or browser helper means the file was saved from the web. An archive tool (7z, WinRAR, tar, unzip, Archive Utility) means it was extracted from a download.
  • On the same host and user, look for a preceding download of a zip, rar, or 7z into the same Downloads folder, and for follow-on writes to .codex, .claude, or other GenAI config paths.
  • Check whether Codex, Claude, or another agent was later started with that Downloads folder as its workspace, and whether it spawned npm, npx, node, or a shell afterward.
  • If the file is malicious, hunt the same filename and content hash on other hosts.

False positive analysis

  • Cloning or downloading a legitimate repository into Downloads extracts a real AGENTS.md or CLAUDE.md. Confirm the archive or URL and the file contents before excluding.
  • Saving those files from a browser while working on an agent project in Downloads is expected. Scope exceptions to a known path, user, or parent archive, not to the filename alone.

Response and remediation

  • Quarantine the instruction file and any archive it came from. Collect the hash and the download URL if present.
  • If an agent already consumed the file, review ~/.codex/config.toml, .claude/settings.json, and other MCP config for new servers or API base URLs, and remove unauthorized entries.
  • Rotate agent login tokens and any credentials the session could have read. Remove packages the agent installed as part of the instructions, such as an unexpected npm package.

References

Related rules

to-top