Prompt injection in OpenHands leaked a GitHub token and achieved remote code execution
2025-openhands-lethal-trifecta-rce · 2025-08-09
A researcher demonstrated that untrusted content processed by the OpenHands coding agent (a website or GitHub issue) could inject instructions that exfiltrate the agent's GITHUB_TOKEN via a rendered Markdown image, and in a second demonstration induce the agent to download and run attacker-supplied malware, joining a command-and-control server. Demonstrated as proofs of concept against the researcher's own instances.
System
- Framework
- OpenHands (formerly OpenDevin) coding agent
- Tools
- shell, web-browser, github-api
- Vendor
- All Hands AI
- Autonomy
- supervised-autonomous
Classification
- Primary class
- prompt-injection
- Chain
- prompt-injection/indirect → data-exfiltration/via-output → unsafe-action/cross-domain-action
- Attack vector
- untrusted-content
- Causation
- entity: human · intentionality: intentional · timing: post-deployment
Trigger
Instructions hidden in content the agent fetches on the fly — a website or a GitHub issue — were followed as if they were user commands. In the first demonstration the injected text directed the agent to locate an environment variable matching a GitHub token subpattern, encode it, and place it in a Markdown image URL that the chat interface renders, sending the token to an attacker server. In the second, the injected text directed the agent to download a binary and execute it, which connected to an attacker-controlled command-and-control server.
Root cause
OpenHands combines the three elements of the "lethal trifecta": access to sensitive data (a repository-scoped GITHUB_TOKEN in its container), the ability to communicate externally (rendering images, posting comments, running shell commands), and exposure to untrusted content it browses autonomously. Content retrieved during a task enters the model context with the same standing as user instructions, and there is no boundary between reading it and taking privileged action on it.
Contributing factors
- The chat interface auto-renders Markdown images, providing a zero-click exfiltration channel.
- A redaction/refusal guardrail on the full token prefix was bypassed by matching a subpattern and re-encoding the value.
- The agent executes shell commands and downloaded binaries without an approval gate.
- Coding agents routinely fetch additional content from the web mid-task, widening the untrusted-input surface.
Detection
Discovered and disclosed by security researcher Johann Rehberger (wunderwuzzi) and documented on the Embrace The Red blog; independently summarised by Simon Willison.
Recovery
Reported privately to All Hands AI on 2025-03-13; the researcher published after more than 90 days without a resolution. Recommended mitigations are architectural rather than a single patch.
Prevention
Treat all fetched content as untrusted; remove or scope down long-lived credentials in the agent container; disable or sandbox auto-rendering of outbound image URLs; require approval before executing downloaded code or crossing trust boundaries; constrain network egress to known destinations.
Blast radius
- Data
- Demonstrated exfiltration of the agent's GITHUB_TOKEN environment variable, a repository-scoped credential, to an attacker-controlled server in a researcher proof of concept. credentials
- User harm
- Potential credential theft and full compromise of the agent container (remote code execution, command-and-control). Shown as proofs of concept against the researcher's own instances. none-reported
- Scope
- any OpenHands deployment that processes untrusted web or repository content
- Reversibility
- irreversible
References
- CWE
- CWE-77, CWE-94
- OWASP LLM
- LLM01 LLM02 LLM06
- MITRE ATLAS
- AML.T0024 AML.T0051
- Tags
- lethal-trifecta coding-agent token-exfiltration rce zombai
Sources
Cite this incident
Permalink: https://swarmproof.github.io/agent-postmortems/2025-openhands-lethal-trifecta-rce/
@misc{2025-openhands-lethal-trifecta-rce,
title = {Prompt injection in OpenHands leaked a GitHub token and achieved remote code execution},
year = {2025},
howpublished = {agent-postmortems},
url = {https://swarmproof.github.io/agent-postmortems/2025-openhands-lethal-trifecta-rce/}
}