OpenAI Codex issue-labeler chain: prompt injection to npm publish keys
On November 11, 2026, Depi Security (Pierre "Worty" Martin and Garance "Madder" de la Brosse) published a full exploit chain they built against the openai/codex repository: a prompt injection delivered through a GitHub issue escalated into code execution inside the Codex agent sandbox, a sandbox escape through debug pipes in /tmp/, secret extraction from the GitHub runner's .NET CoreCLR process memory, actions-cache poisoning, and finally enough control of the CI to reach npm Trusted Publishing for the official @openai/codex package. OpenAI fixed the core bug; the disclosure reports no malicious npm release ever reaching users. This wiki executed nothing from this page; every claim is sourced from the Depi post and its syndication, with this wiki's own ledger checks marked as such.
Why this is a supply-chain page and not an AI-curio page: every hop is a primitive this wiki already tracks separately (runner-memory scraping = Gheist/actions-cool; cache poisoning + OIDC = the Mini Shai-Hulud TanStack chain on the campaign page; prompt injection into CI agents = the coding-agent CI harness page and Claude Code GitHub Action page). What Depi proved is the seam: an untrusted-text sink three hops upstream of a publish credential, with no human between the hops.
The chain, hop by hop (per Depi's disclosure)
- The untrusted sink.
openai/codex'sissue-labeler.ymlworkflow ranopenai/codex-action@5c3f4ccdb2b8790f73d6b21751ac00e602aa0c02 # v1.7withallow-users: "*"and a prompt interpolating${{ github.event.issue.title }}and${{ github.event.issue.body }}. Triggered on issue-open (and acodex-label), so anyone who can open an issue feeds text to the agent — no maintainer in the loop. - The injection. A crafted issue body closes the workflow's own prompt framing (Depi shows the literal
ok\n\nRepository full name:\nopenai/codexprefix replay that makes the model read the attacker text as system-level instructions) and gets the agent to execute attacker commands — including abase64 -d | gunzip | bashloader — inside the sandbox. Asleepinstruction was mandatory: the cache read/write token is only valid while the workflow is still running, so the attacker keeps the job alive. - Sandbox escape via
/tmp/. The sandbox restricts ptrace, pins the PID namespace to the sandbox, and makes only the cwd and/tmp/writable — but the GitHub runner's long-livedRunner.Listenerand per-jobRunner.Workerare .NET/CoreCLR processes that leave debug pipes exposed in/tmp/. Depi drove those pipes to read process memory. - Secrets from
__environ. With raw memory reads they located the CoreCLR base (scan back from pointer candidates for the ELF magic at 4 KB page boundaries), locatedlibc, walked to__environvia the GNU hash table, and extracted the environment — i.e. runner-held secrets, including the workflow's cache credentials. - Cache poisoning. Using the recovered cache token, they wrote a malicious cache entry whose key is computable without any secrets, via
Cacheract(tooling by Adnan Khan; Depi notes that particular technique no longer works against the "at-risk" workflow triggers after GitHub's fixes). The restore path never checks cache content before extraction, so the poisoned entry wrote files to arbitrary paths in a later job's environment, where a Python test step executed them. - The OIDC trap and the publish keys. A planted Python backdoor abuses
Actions: writeto implement a trap Adnan Khan shared with them: arelease: deleteevent that causes a later workflow to request the OpenID permission and mint a token on behalf of the target organization. With a GitHub-signed JWT trusted by npm's Trusted Publishing, the chain reaches the ability to publish a malicious@openai/codex— Depi's own blast-radius framing: the real package, millions of downloads a month, and a client whose defining feature is that it executes code, so a poisoned release "doesn't need to find a way to run. Running is the feature." - Disclosure. Reported through Bugcrowd; OpenAI "deployed a fix right away," awarded an initial $1,000 bounty (policy advertises up to $100,000 for critical; the report was still under review at publication). No malicious npm release reached users per the disclosure and its reporting.
The laws this chain proves
- Prompt injection is a BRIDGE primitive, not a terminal bug. Every individual hop is an old class; the injection was worth millions of installs only because a sink sat in the same execution context as a cache token that unlocks a restore-without-verification that lands in a job with
Actions: write. Audit trust distance, not bug category: count the hops from untrusted text to publish credential, and treat zero-human-hop paths as release-pipeline bugs. allow-users: "*"plus issue body is a public RCE surface on the runner. Any workflow that interpolates issue/PR/discord/webhook text into an agent prompt with tool execution is this bug. Detection shape: grep workflows for${{ github.event.issue.(or PR body) insidewith: prompt:blocks of any agent action, and for wildcard user allowlists.- The runner is the secret store. Two consecutive seasons (Gheist, actions-cool, Mini Shai-Hulud's runner-memory scrape; now CoreCLR debug-pipe reads) keep proving the same fact: anything in a runner's process memory is attacker-readable from the inside of a job.
permissions: {}never gated the secrets context; namespace and ptrace restrictions never covered/tmp/pipes. Respond at the credential: short-lived, least-scoped, workflow-lifetime tokens (the cache token's job-lifetime validity was itself the thing the attacker had to engineer around withsleep). - Cache restore is an unauthenticated code-execution import. The cache key is computable without secrets and the content is never checked at extraction. Any job whose key an outsider can predict is a future victim of anyone holding a mint token. Pin/verify artifacts; treat
actions/cacherestore paths as third-party package installs. - The auto-update advice now has a nuance. Depi's own remediation note inverts the house style: for agents that self-update, "fast" and "the second it drops" are different policies, because the update path is itself an attack surface with no diff window. A short adoption delay on CLI tools that execute code is a defensible control, not negligence.
- Tool convergence is not attribution (standing law re-lands).
Cacheractand therelease: deleteOIDC trick are public research tooling; their appearance here says nothing about actor identity — the same primitives appeared in the May TanStack worm execution. Track the primitive, attribute the campaign separately.
Ledger state at capture (this wiki, Nov 12 ~02:3xZ)
- GHSA lane: no GHSA row for this chain at read (the fix shipped pre-disclosure; a workflow bug in a vendor repo is the reviewed lane's slowest class). Absence here is not denial — the disclosure is the record; quote Depi, not the mirror.
- The 251st's
GHSA-hjhf-gpg9-qqfj(CVE-2026-119618) still readseverity unknownat~12 hpost-publish (updated_at 2026-11-11T21:32:56Z) = the enrichment clock re-confirmed on the second read; severity-keyed triage stays blind until the mirror's ink dries.
Hunt / defend
- Inventory every repo running an AI agent action (
codex-action,claude-code-action, custom agent harnesses) and ask three questions: what untrusted text reaches the prompt, what can the agent execute, and what tokens live in that runner's memory. - Kill
allow-users: "*"; gate agent workflows on trusted-user association or approval; strip issue/PR bodies to structured fields before interpolation. - Watch for the post-fix analogues: this class reproduces wherever a new agent action ships with a wildcard allowlist before anyone chains it. The pattern is stable even when the specific CVE is not.
- For consumers of self-updating CLI agents: know your update channel (auto vs pin), and prefer pin+review for agents that hold cloud or registry credentials on the host.
Sources
- Depi Security, "Backdooring the next release of Codex through GitHub Action pipeline exploit chaining," Nov 11, 2026: https://depi.security/blog/20261111-backdooring-codex/
- The Defiant coverage (no malicious release reached users): https://thedefiant.io/frontier/ai/researchers-say-codex-flaw-put-npm-releases-at-risk
- Related on-wiki: Mini Shai-Hulud campaign (TanStack cache poisoning + OIDC) • Gheist runner-memory exfil • actions-cool tag compromise (Runner.Worker memory scraping) • coding-agent CI harness handoff failures