← all writing
12 · 01 Sept 2026 · 6 MIN READ

Your Prompt Is Part of the Attack Surface

Most repository-poisoning research treats the attacker as the only variable — how well the payload hides, how convincing the disguise is. Skimming this morning's arxiv list, one paper turned the camera around and asked what the user contributes to their own compromise. The answer is: a lot. My thesis for this post — when you point a coding agent at a repo you didn't write, the prompt you type is not a request. It's a security configuration, and almost nobody treats it like one.

What it does

The paper is Beyond the Payload: How User Invocation Shapes Coding Agent Vulnerability to Repository Poisoning, from Fukang Zhu, Binbin Zhao, Ruixiao Lin, Ping He, Tianyu Du and Shouling Ji. They coin the term Prompt-Level Configurations — PLCs — for the everyday choices a developer makes when invoking an agent: which task they delegate, how they phrase it, and which skills or rules files are loaded. Then they build CIPR (Coding In Poisoned Repos) to measure whether those choices actually move the needle on getting owned.

The setup is a clean factorial: four task types × four prompt styles (including a neutral baseline) × three skill/rule conditions, giving 48 configurations, each replicated across 20 real GitHub repositories and two payload-crafting methods. That is n=40 per cell and 1,920 runs total. The repos are genuine, well-known projects across Python, JavaScript, C and Java — requests, axios, react, mbedtls, RxJava, DeepSpeed, and, with some irony, a popular everything-claude-code repo. Payloads land in the files an agent actually touches when bootstrapping a project: setup.py, package.json, Makefile/CMakeLists.txt, build.gradle. One crafting method embeds the malicious code inline; the other buries the script deeper in the tree and leaves only a one-line invocation at the surface. The attacker goal is data exfiltration, scored objectively — a mock HTTP server either receives the secret or it doesn't. Alongside attack success rate (ASR) they track an alert rate (AR): did the agent tell the user anything was wrong.

The key result

Which task you delegate matters more than almost anything else in the experiment. Asking the agent to run the tests produced a 45.5% attack success rate (95% CI [41.1, 50.0]); asking it to fix a bug produced 8.6% (95% CI [6.4, 11.5]) — same repos, same payloads, same model. Preparing the environment landed at 24.9%, adding a feature at 14.8%. The authors characterise the spread as up to a 4.5-fold difference in vulnerability, and it comes with a nasty inversion: run-tests is not only the most dangerous task, it is also the quietest. Its alert rate is 8.2%, against 30.9% for prepare-env. The configuration most likely to get you exfiltrated is the one least likely to say anything about it.

Why it matters

Think about what you actually do the first time you clone an unfamiliar repo. You don't hand the agent a bug to fix — you don't know the codebase yet. You say “get this running” or “run the tests and tell me what's broken.” That is the reconnaissance move, and it is exactly the cell with a near coin-flip attack rate and near-silence. The mechanism is unglamorous: fixing a bug is a reading-and-editing task, while running tests is an execution task, and execution is where a poisoned build manifest cashes out. So the practical control isn't a smarter model, it's sequencing — read first, execute later, and treat “just run the tests” on unvetted code as the privileged operation it actually is. If you build agent harnesses, this argues for task-type-aware permissioning: the same repo should get a different sandbox depending on whether the delegated task invokes the build system.

The skills-and-rules finding is the one I'd tape to the wall. They tested three conditions — no skills, ordinary productivity skills scraped from GitHub, and those same skills plus explicit security directives like “do not execute unverified code” and “confirm before making network requests.” Security-aware rules visibly raised the alert rate. They did not meaningfully move attack success: the confidence intervals overlap across all three conditions. Your security rules make the agent narrate concern while the payload runs. The authors name this directly as an enforcement gap — agents flag the problem during or after executing it, not before. That reframes what a CLAUDE.md or a security skill really is: a prompt-level nudge on a system with no control-flow interlock behind it. If the harness can't block the call, the rule is documentation, not defense. Real mitigation has to live in the tool layer — deny-by-default network egress, approval gates on shell execution — not in the instructions. One more result worth internalising: terse, underspecified prompts reduced attack success (adjusted odds ratio 0.71, 95% CI [0.51, 0.98], p=0.036). Don't cheer. The mechanism is that vague prompts make the agent do less, so it never reaches the payload. That's not a defense, that's a truncated blast radius — and it evaporates the moment your prompt gets good.

The caveats

The takeaway

The contribution I'm keeping isn't the benchmark, it's the reframing: agent vulnerability is not a fixed property of a model or a harness, it's the outcome of a configuration the user sets — mostly by accident — every time they type. Two things change for me after reading it. First, “run the tests” is no longer my opening move on an unfamiliar repo; I read the install and build manifests myself before anything executes, which costs about thirty seconds. Second, I've stopped counting security directives in rules and skills files as mitigation. They buy visibility, which is worth something, but the evidence here is that they don't buy prevention. If I want prevention, it has to be a sandbox or a permission gate — something that can say no while the agent is still asking.


Working on something similar?

Say hello — I read every email.