The Attack BrassCoders Can't Catch: Prompt Injection

Prompt injection is a runtime attack on the AI agent reading your repository, not a pattern in the code it writes. No source scanner sees it. Here's where the exposure is and where the mitigations actually live.

Copper Sun Brass Team · · 5 min read
securityai-code-reviewengineering

BrassCoders scans source code deterministically, and prompt injection is a class of attack it cannot catch, because prompt injection is a runtime attack on the AI agent reading your repository rather than a pattern in the code the agent writes. Researchers measured attack-success rates as high as 84% against GitHub Copilot and Cursor once the agent ingested poisoned external content. Knowing where a source scanner stops is worth as much as knowing what it catches.

Most vendor security posts claim their tool covers the risk. This one draws the boundary instead. There is a whole layer of AI-code risk that no static analyzer reaches, and pretending otherwise would leave you exposed at exactly the point you thought you were covered.

What Prompt Injection Actually Is

BrassCoders indexes prompt injection as OWASP’s LLM01, the top-ranked risk in the Top 10 for LLM Applications, because it’s the attack most likely to reach an AI-augmented codebase. Prompt injection is when text the agent reads gets treated as instructions to follow. For coding agents the dangerous form is indirect injection, where the payload hides in a README, a GitHub issue, or a dependency’s documentation that the agent ingests while doing its job.

The model cannot reliably tell operator instructions from attacker text embedded in the content it was told to work on. You point the agent at a repository; the repository contains a line that reads like an instruction; the agent follows it. The malicious repo passes human review because the injected text looks like ordinary prose, and the attack fires only when an agent reads it.

How Exploitable Copilot and Cursor Are

BrassCoders points to the strongest measurement of this exposure: Liu et al. built AIShellJack, a framework of 314 attack payloads covering 70 MITRE ATT&CK techniques, and ran it against GitHub Copilot and Cursor with attack-success rates reaching 84% for executing malicious commands. The paper, “Your AI, My Shell”, documents objectives that ranged from initial access and system discovery to credential theft and data exfiltration.

The 84% figure applies to agents that auto-run commands against untrusted content. An agent configured to execute without confirmation, pointed at a repository an attacker seeded, will run the attacker’s commands most of the time. That is not a tuning problem a better model fixes. It’s a property of letting an agent act on instructions it read from untrusted input.

The Lethal Trifecta

BrassCoders uses Simon Willison’s lethal trifecta as the clearest model for when prompt injection turns into data theft: an agent that has access to private data, exposure to untrusted content, and the ability to communicate externally. Any agent holding all three can be steered by injected instructions into reading secrets and sending them to an attacker.

An AI coding agent tends to have the full set. It has repository access, so it reads your private code and credentials. It ingests untrusted content, every dependency’s docs and every issue in the tracker. And it has network egress, to fetch packages and call APIs. Willison’s practical advice is the cheapest defense available: remove any one leg and the exfiltration path closes.

Why a Source Scanner Can’t See It

BrassCoders matches structural patterns in committed source — a SQL string built by concatenation, an md5 call, a hardcoded key — and a prompt-injection payload is none of those things. The payload lives in the content the agent reads at runtime, a GitHub issue or a web page, not in the code the agent writes. There is nothing in the repository’s Python for a scanner to flag.

This is the boundary of deterministic source analysis, and it’s worth stating plainly. BrassCoders is a pattern reporter for code; prompt injection is an attack on an agent’s runtime behavior. A scanner that claimed to detect it would be inferring intent from content it has no way to evaluate, and a false sense of coverage is worse than a clear boundary. The accurate answer is that this class of attack sits outside what any source scanner can see.

Where the Mitigations Live

BrassCoders points to Anthropic’s Claude Code security documentation as a concrete example of where prompt-injection defenses actually operate: the agent runtime. The documented controls are runtime controls, a permission system that requires explicit approval for sensitive operations, isolated context windows for web fetches so retrieved content cannot inject instructions, trust verification for first-time codebases and new MCP servers, and command-injection detection that forces manual approval of suspicious commands.

The threat reaches past the editor. The Cloud Security Alliance documented a 2026 case where an AI coding agent’s GitHub Action had a permission check that trusted any GitHub App actor, letting an external attacker inject a malicious prompt through a single crafted issue and escalate toward repository compromise without write access. Agent plus automation plus untrusted input is a live supply-chain vector, so the same permissioning discipline applies in CI as in the editor.

What BrassCoders Covers Instead

BrassCoders scans the code the agent produces for the deterministic patterns AI assistants ship at measured rates: SQL injection, command injection, weak cryptography, and hardcoded secrets. Those are structural, they live in the committed source, and they are exactly what a pattern scanner catches the same way on every run.

The two layers are complementary and neither replaces the other. Runtime controls harden the agent against instructions it reads; a source scan catches the insecure code the agent writes. Configure the permissioning and sandboxing to close the prompt-injection path, then run a deterministic scan on the output so the code that ships is clean.

pip install brasscoders
brasscoders --offline scan /path/to/your/project

The scan catches the patterns in your code. Prompt injection needs runtime hardening, not a scanner, and a tool worth trusting tells you where it stops.

Frequently Asked Questions

Can BrassCoders or any static analyzer detect prompt injection?

No. Prompt injection is a runtime attack on the AI agent, not a pattern in the source code the agent produces — there is nothing in the committed code for a scanner to match. BrassCoders scans source deterministically; prompt-injection mitigations live in agent permissioning, sandboxing, isolated context windows, and egress control. The two operate at different layers and neither substitutes for the other.

How exploitable are Copilot and Cursor to prompt injection?

Highly, when they auto-run commands against untrusted content. Liu et al. (2025) built AIShellJack, a framework of 314 payloads across 70 MITRE ATT&CK techniques, and measured attack-success rates as high as 84% for executing malicious commands on GitHub Copilot and Cursor after the agent ingested poisoned external content.

What is the lethal trifecta?

Simon Willison's model for when prompt injection becomes data theft: an agent with access to private data, exposure to untrusted content, and the ability to communicate externally. An AI coding agent with repository access, an untrusted issue or dependency in context, and network egress has all three, and removing any one leg is the cheapest mitigation.

How do I defend an AI coding agent against prompt injection?

Break the lethal trifecta and add runtime controls. Require explicit approval for command execution rather than auto-approve, sandbox the agent's filesystem and network, isolate the context window used for web fetches so retrieved content cannot inject instructions, and restrict network egress. Anthropic's Claude Code security documentation describes a concrete implementation of these controls.