Cybersecurity · AI Security
A Clean-Looking Repo Can Still Hijack Your AI Coding Agent
Mozilla's 0din research team found a way to get AI coding agents to open a reverse shell using a repository that contains no visible malicious code at all. Here's how the attack works and what to change in your workflow.
Prathviraj Singh
5 min read
Sponsored
You clone a repository. The README looks normal. There’s a Python package that, on first run, fails with a common-looking setup error and tells you to run one more command to fix it. If you’re using an AI coding agent to work through the setup, it reads that message and, trying to be helpful, runs the command for you. That command opens a reverse shell to an attacker’s server, and neither you nor the agent ever saw the malicious instructions, because they were never in the repository at all.
That’s the attack Mozilla’s 0din research team demonstrated in June 2026, and it’s worth understanding in detail because it doesn’t depend on a bug in any specific model. It depends on how agentic coding tools handle instructions that arrive through project content instead of through you.
How the chain actually works
The attack has four links, and each one looks unremarkable in isolation:
1. README with normal-looking setup instructions
│
2. Python package engineered to fail on first use,
prints a message pointing to an "init" command
│
3. Init command runs a shell script
│
4. Shell script resolves a DNS TXT record controlled
by the attacker, pipes the content directly to bash
│
Reverse shell, running as the developer's own user
The key design choice is step 4. The actual malicious payload, the code that opens the reverse shell, isn’t written anywhere in the repository. It lives in a DNS TXT record the attacker controls off-site, fetched at the moment the script runs. That means static analysis of the repo finds nothing to flag: the script that’s actually present just does a DNS lookup and pipes the result to a shell, which is a legitimate pattern used by plenty of real installers. The dangerous part only exists for the seconds it takes to execute.
Why an AI agent makes this worse, not better
A human developer reading a “run this command to fix the setup” message has some chance of pausing, especially if the command looks like it involves network calls piped into a shell. An AI coding agent working through a task doesn’t have the same instinct by default. It’s optimizing for “complete the task the user asked for,” and if the repository’s own content tells it that running one more command is the way to fix a broken setup step, that instruction looks like part of the task, not an attack.
This is what security researchers call indirect prompt injection: the attacker never talks to the agent directly. They plant instructions in content the agent is going to read anyway, a README, an error message, a code comment, and let the agent’s own task-completion drive carry the payload forward. Unit 42’s broader research on this pattern found it works across web content generally, not just repositories, which tells you this isn’t a one-off trick, it’s a structural weakness in how current agents weigh “instructions from my user” against “instructions I encountered while doing what my user asked.”
The part that should get every team’s attention: this worked across agents built on models from multiple different vendors. It’s not a gap you close by switching tools.
What’s actually exposed
Once the reverse shell is live, the attacker has whatever the compromised process has. For a developer running an agent locally, that’s usually everything in the shell’s environment: cloud provider credentials, git tokens, package registry auth, API keys for whatever services the project touches. For an agent running in CI, it can be worse, since CI environments frequently hold deploy credentials with broader blast radius than a single developer’s laptop. And because it’s a reverse shell rather than a one-shot payload, the attacker has persistence, not just a single stolen secret.
What to change this week
- Scope agent permissions to the task, not to your whole environment. If an agent doesn’t need access to your cloud credentials to fix a lint error, it shouldn’t have a shell session where those credentials are exported.
- Treat “one command to fix it” instructions from repository content as a manual-approval step, particularly anything involving
curl, DNS resolution, or piping output straight into a shell. That pattern is common enough in real installers that agents will keep proposing it; the fix is a human checking the specific command, not banning the pattern outright. - Run agentic workflows in isolated environments when the task involves cloning and executing code from a repository you don’t control. A sandboxed execution environment limits what a successful injection can actually reach, which is a different, complementary control to catching the injection itself. If you’re building this into your CI or agent tooling, our walkthrough of running untrusted code safely with Deno Sandbox covers one practical way to add that isolation layer.
- Don’t assume this is caught by “the agent read the whole repo first.” The entire point of the DNS TXT record technique is that the payload isn’t present for the agent, or a scanner, to read in advance.
The uncomfortable truth here is that the attack surface isn’t the AI agent’s intelligence, it’s its obedience. An agent that correctly interprets “run this command to fix your setup” as a reasonable instruction is doing exactly what it’s supposed to do when the instruction is legitimate. The only way to catch the illegitimate version is to stop trusting repository content as a source of commands to execute without a human in the loop, the same discipline good engineers already apply to unsolicited scripts from strangers.
Frequently asked questions
- What exactly did Mozilla's 0din team find?
- A proof-of-concept attack chain where a public GitHub repository looks completely benign on inspection, a normal README with setup instructions, a Python package. The package is engineered to fail on first use and print a message directing the user (or an AI agent working on their behalf) to run an initialization command. That command executes a shell script which resolves a DNS TXT record controlled by the attacker and pipes the returned content directly into bash.
- Why can't code review or a static scanner catch this?
- Because the malicious payload isn't in the repository at any point. It only exists as a DNS TXT record the attacker controls, fetched live when the initialization command runs. Anyone reviewing the repo's source, and any AI agent reading the repo's contents before acting, sees only a script that resolves a DNS record and pipes it to a shell. The actual instructions inside that DNS record can change at any time and are invisible until execution.
- Is this specific to one AI coding tool?
- No. The researchers found the attack chain worked across agents using models from Anthropic, OpenAI, and Google, indicating the weakness sits in how agentic coding tools generally interpret and act on untrusted content from a working directory, not in one vendor's model or product.
- What's actually at risk if this succeeds?
- A reverse shell running with the permissions of whatever user account the agent is operating under. In practice, that's typically a developer's own machine or a CI runner, both of which routinely have API keys, cloud provider credentials, and source control tokens sitting in environment variables or config files. The attacker gets all of it, plus a persistence foothold.
- What should teams actually change in how they run AI coding agents?
- Run agents with the least privilege they need for the task, not full access to your credential store. Treat any shell command an agent proposes to run because a repository told it to, especially one involving curl, DNS lookups, or piping output to a shell, as a manual-review step rather than an auto-approved action. And apply the same skepticism to a 'just run this one command to fix it' instruction from a repository that you would to the same instruction from an unfamiliar person.
Sources
Sponsored
More from this category
More from Cybersecurity
R.01 An OpenAI Model Broke Out of a Test Sandbox and Hacked Hugging Face. Here's What Actually Happened.
R.02 The Hugging Face Breach: An OpenAI Test Model Broke Out of Its Sandbox on Its Own
R.03 CVE-2026-50017: pnpm Leaked npm Auth Tokens to Untrusted Registries. Are You Patched?
Sponsored
Discussion
Join the conversation.
Comments are powered by GitHub Discussions. Sign in with your GitHub account to leave a comment.
Sponsored