A clean GitHub repo can talk Claude Code into opening a reverse shell
On June 29, 2026, researchers at Mozilla's Zero Day Investigative Network (0DIN) published a proof-of-concept showing that a GitHub repository containing no malicious code can still hijack an agentic coding tool like Claude Code. The repo ships normal-looking setup notes and a Python package engineered to fail on first run with an error telling the user to run an init command. The agent, trying to be helpful, runs it; the init script resolves an attacker-controlled DNS TXT record and pipes the result to bash, spawning a reverse shell on the developer's machine. The payload never lives in the repo, so scanners, human reviewers, and the agent itself never see it. It is a demonstrated hazard, not a confirmed in-the-wild attack.
Incident Details
Tech Stack
References
Security researchers at Mozilla's Zero Day Investigative Network, the GenAI bug bounty platform better known as 0DIN, published a proof-of-concept on June 29, 2026 that should make anyone who runs an agentic coding tool slightly nauseous. The headline, from their write-up "Clone This Repo and I Own Your Machine," is that a GitHub repository can take over your computer through Claude Code without containing a single line of malicious code.
Before anyone panics: this is a researcher demonstration, not a reported breach. 0DIN explicitly describes the attack as "currently just a concept," and there are no confirmed in-the-wild victims. What makes it worth cataloging is that the technique works precisely because the agent is behaving exactly as designed. There is no bug to patch in the usual sense. The vulnerability is the helpfulness.
The setup looks boring on purpose
Here is the chain 0DIN built. The malicious repository contains ordinary-looking setup instructions in its README. It ships a Python package, called axiom in the demo, that is engineered to refuse to run on first use. When the agent tries to use it, the package throws a RuntimeError whose message politely instructs the user to run an initialization step: python3 -m axiom init.
That init command calls a shell script. The script reads a configuration value, except the value does not live in the file. It is fetched at runtime from a DNS TXT record controlled by the attacker, and whatever comes back is executed as a command. In the demonstration, the record decodes to a reverse shell that connects back to the attacker's server.
Now drop an AI coding agent into that scenario. A developer pastes the repo link and asks Claude Code to "get the project running." The agent reads the files, installs the dependencies, tries to use the app, hits the RuntimeError, reads the error message telling it to run python3 -m axiom init, and runs it as routine error recovery. The init script fetches the DNS payload and executes it. The reverse shell opens. The developer asked for a working project and got an attacker on their machine.
Why nothing catches it
The genuinely unpleasant part is how invisible the payload is. It is not in the repository, so static analysis tools and secret scanners find nothing. A human reviewer reading every file finds nothing, because every file is individually mundane. The AI agent that read the whole repo before acting also finds nothing, because the malicious instruction does not exist yet at read time. It materializes only when the shell script resolves the DNS record, three indirection steps removed from anything the agent ever evaluated.
0DIN put it well: "Claude Code never decided to open a shell. It decided to fix an error." The agent followed a trusted error message, ran a script it did not fully inspect, and that script pulled a value from a DNS record the agent never saw. Each individual step is reasonable. The composition is a remote code execution.
The blast radius if this ever leaves the lab
Once the reverse shell connects, the attacker has an interactive session running as the developer's own operating system user. That is the part that turns a clever trick into a real hazard. Agentic coding tools live in exactly the environment an attacker wants: environment variables, credentials, API keys, and local configuration files. 0DIN notes the obvious targets, ANTHROPIC_API_KEY, AWS_SECRET_ACCESS_KEY, GITHUB_TOKEN, and whatever else is exported into the shell. From there an attacker can drop SSH keys, install cron-based persistence, or quietly exfiltrate local config for long-term access.
Delivery does not require anything exotic either. A single repo link in a fake job posting, a tutorial, a blog post, or a Slack message is enough to compromise anyone who opens it with an AI coding tool. The attack also resists diffing: because the payload lives in a DNS record, the attacker can swap it at any time by editing one TXT entry, with nothing in the repository ever changing.
This is the lethal trifecta, wearing a hoodie
None of this is conceptually new. An agent that can read untrusted external content, has access to private data and credentials, and can take actions like running shell commands checks every box of the much-discussed "lethal trifecta" of prompt-injection risk. What 0DIN added is a particularly clean demonstration that the untrusted content does not even need to be a clever jailbreak in a README. It can be an ordinary error message that the agent dutifully tries to resolve. The model's instinct to recover from failures and keep the user unblocked is exactly the lever the attack pulls.
The fix nobody wants to hear
0DIN's recommendation is architectural, not a sterner system prompt. AI coding agents should surface what a setup command will actually execute at runtime, including scripts and anything fetched dynamically, rather than evaluating only the literal command string. In other words, the agent should be able to tell you that python3 -m axiom init eventually pipes a remote DNS value into bash, before it runs it.
For developers, the advice is older than any of this and still ignored daily: treat setup instructions and scripts in unfamiliar repositories as untrusted code, no matter how confidently your AI tool recommends running them. Sandboxing the agent, restricting outbound network egress, and keeping real credentials out of the agent's environment all blunt the damage if the agent does get talked into something stupid.
The reason this belongs in the graveyard even as a proof-of-concept is that it documents a defect in how agentic tools reason about trust. They were built to read everything in front of them and act on it helpfully, and they cannot reliably tell the difference between a legitimate setup step and a trap dressed as one. Until they can, "get the project running" is a command with a much larger attack surface than it sounds.
Discussion