system: OPERATIONAL
← back to all hacks
AGENTS CRITICAL NEW

Context privilege escalation: untrusted text gets promoted inside 12 coding agents

A 1 September 2026 paper shows low-trust content can be promoted into higher-privilege message roles and more persistent scopes across 12 agent harnesses, including Claude Code and Codex.

2026-09-02 // 8 min affects: claude-code, codex, gemini-cli, qwen-code, kimi-cli, aider, opencode, cline, goose, pi-mono, openclaw, hermes-agent

What is this?

An AI agent is a model plus a harness — the code that decides what goes into the context window, from which files, and with which privilege label. Providers define a role hierarchy for those labels (OpenAI uses system, developer, user, assistant, tool, from most to least trusted) and train models to prefer higher roles when instructions conflict. That hierarchy is the main structural defense the industry has against indirect prompt injection.

On 1 September 2026, Zichuan Li, Jian Cui, Ashley Chen, Xiaojing Liao and Luyi Xing (University of Illinois Urbana-Champaign) published What’s in Your Agent’s Context? Context Privilege Escalation Attacks against AI Agent Harness (arXiv:2609.01222). It is, per the authors, the first systematic security analysis of how real harnesses assemble context.

The finding: the hierarchy holds inside the model, but the harness leaks around it. Attacker text that entered as low-privilege tool output can be relabelled upward or made persistent, without the attacker ever touching the machine. The authors name two classes:

  • M-CPE (message-role context privilege escalation) — content from a low-privileged source ends up carried in a higher-privileged message role.
  • X-CPE (cross-scope context privilege escalation) — content persists beyond the context it was introduced in, surviving agent restarts and following the user into other projects.

They ran end-to-end proof-of-concept attacks against 12 high-profile harnesses, including Claude Code, Codex, Gemini CLI, Cline, OpenCode, Goose, Aider, Qwen Code, Kimi CLI, Pi-mono, OpenClaw and Hermes Agent.

How it works

The paper catalogues 16 attack vectors in three categories, all of which reduce to the same move: get the harness to copy your text into a slot it trusts more.

Diverse context sources. Harnesses load far more than the documented memory file. Claude Code searches for CLAUDE.md in directories it touches at runtime — so an untrusted archive that was merely extracted, never executed, can drop a memory file the agent then reads at a higher role. Gemini CLI additionally does a downward breadth-first search from its launch directory, meaning a file placed deep inside a checked-out pull request tree gets loaded whether or not the pull request is approved. Several agents also assemble environment information: Claude Code shells out to git log --oneline -n 5 at launch and places the output in system-level context, which turns a commit message into an instruction channel.

Context markup. Nearly every harness separates context segments with XML-ish tags — <available_skills>, <skill>, <description>, <system-reminder>. These are plain text, not special tokens. Content that contains a matching closing tag escapes its own container, and text after it reads as if it belonged to the surrounding, higher-trust block. Some harnesses go further and parse tags out of model output to trigger tool calls, so echoed content becomes an action.

Assembly logic. Load-order rules are exploitable on their own. Codex prefers AGENTS.override.md over AGENTS.md when both exist — so a pull request that adds an override file to a repo running Codex in CI replaces the maintainer’s review instructions with the contributor’s. Recursive @path imports in memory files let one injected line pull in an arbitrary tree of additional content.

# Shape of the escalation — no working payload
[ r4 tool output ]  attacker-controlled web page / archive / commit message

        │  harness copies, discovers, or relabels

[ r0-r2 ]  memory file · skill description · config · environment block

        │  scope widens: session ──> project ──> user

   reloaded at every launch, in every future session

To measure this at scale the authors built CoRA (Context Risk Analyzer), an LLM-assisted pipeline that statically identifies context sources and their roles from harness source, validates them by running the harness, then auto-generates proof-of-concept exploits from the vector taxonomy. Across the 12 harnesses CoRA reported 282 context sources vulnerable to CPE. The proof-of-concept attacks succeeded under GPT-5.5, GPT-5.4-mini and DeepSeek-V4-Flash. Demonstrated outcomes include manipulated tool and skill invocation, denial of service, full agent compromise and remote code execution — the published Claude Code demo chains runtime skill discovery with inline command syntax inside a downloaded website template.

Why it matters

Most agent hardening advice assumes the boundary between trusted and untrusted content is drawn once, at ingestion. CPE says the boundary is redrawn continuously, by harness code the user cannot see and the vendor rarely documents. You can review every tool output and still lose, because the dangerous step happens after review — when the harness decides that this particular file, in this particular directory, deserves a higher label.

Three consequences are worth separating.

Code review is a direct target. The pull-request scenarios are not hypothetical framing: a repository that runs an agent in CI to review contributions accepts attacker-authored files, directory names and commit messages by design. The instructions land in context regardless of the review verdict.

Persistence changes the risk profile. Ordinary indirect injection dies when the session ends. X-CPE writes into files that reload at every launch, which converts a one-shot injection into a foothold that follows the developer to unrelated projects.

Opacity is the root cause. Users cannot enumerate what their agent loads, from where, or at what role, because that logic is proprietary and undocumented. That is the authors’ central complaint, and it is a design problem rather than a bug list.

Defenses

Update your agents. Codex and Gemini CLI have shipped versions mitigating parts of this. Check your harness version against the paper’s table before assuming you are covered.

Treat every file inside untrusted content as untrusted, including memory and skill files. A CLAUDE.md, SKILL.md, AGENTS.md or .cursor/rules file arriving in a downloaded archive, a dependency, or a pull request branch is attacker input wearing a configuration file’s name.

Do not run agents from directories containing unreviewed third-party trees. For CI review workflows, launch the agent outside the checkout, or strip agent-recognised configuration files from the branch before the agent starts. Watch specifically for override-named variants of your instruction files.

Enforce with code, not with prompts. Vendor documentation is explicit that memory files are context, not enforced configuration: Anthropic states that to block an action regardless of what the model decides, you need a PreToolUse hook. Deny-lists, hooks and sandboxes hold when role labels do not.

Constrain imports and load paths. Disable or approve recursive @path imports, and exclude memory files you did not author — Claude Code exposes claudeMdExcludes for exactly this, and prompts before loading external imports from a project file.

Audit what actually loaded, every session. Claude Code’s /context lists the memory files in play, and the InstructionsLoaded hook logs which instruction files loaded and why. If you cannot enumerate your agent’s context sources, you cannot reason about their privileges.

Neutralise markup in wrapped content. If your harness wraps third-party text in tags, escape or strip those tag sequences from the content before assembly. Boundary tokens that an attacker can type are not boundaries.

Keep environment metadata out of high-trust roles. Commit messages, branch names, directory names and file names are attacker-controllable in a collaborative repository. They belong in the lowest role available, not in the system block.

Status

ItemReferenceDateNotes
Primary paperarXiv:2609.01222, Li, Cui, Chen, Liao, Xing (UIUC)2026-09-01Two attack classes (M-CPE, X-CPE); 16 vectors; 282 vulnerable context sources
Harnesses analysedCodex, Claude Code, Gemini CLI, Qwen Code, Kimi CLI, Aider, OpenCode, Cline, Goose, Pi-mono, OpenClaw, Hermes Agent2026-09-01All 12 subject to end-to-end proof-of-concept attacks
Models used in PoCsGPT-5.5, GPT-5.4-mini, DeepSeek-V4-Flash2026-09-01Attacks are harness-level, not model-specific
ToolingCoRA (Context Risk Analyzer)2026-09-01Authors state source will be released with the paper
Public demosProject site, zichuan.li/LLMAgentCPE2026-09-01Includes a Claude Code skill-discovery-to-RCE walkthrough
Responsible disclosureReported to all 12 vendors/maintainersCodex and Gemini CLI have released mitigating versions; work with other vendors ongoing
Vendor guidanceAnthropic Claude Code memory documentationCurrentMemory files are context, not enforcement; claudeMdExcludes, external-import approval, PreToolUse hooks
Mapped frameworksOWASP LLM Top 10 (LLM01 prompt injection), OWASP Agentic Security Initiative2026Privilege and tool-misuse categories

No exploitation in the wild is documented. The paper’s own mitigation discussion favours reducing the number of context sources, filtering escalation attempts, and making harness context assembly transparent to users — the last of which no vendor currently provides in full.

Sources