TLDRocket
Sign in

Escaping the OpenAI Codex sandbox, twice

Accomplish Covered by 2 sources

OpenAI’s Codex sandbox was broken two different ways. Both escapes were fixed in eight days, and both show why trusting code to guard itself is a bad idea.

Based on reporting by Accomplish — read the original for the full story.

Summary, retelling and take written by AI under human oversight; images are AI-generated illustrations. How we work · Report an error

We found two separate ways out of OpenAI’s Codex sandbox and reported both on August 12, 2026. OpenAI fixed them within eight days. The uncomfortable part is not just that they were broken, but how ordinary the failures were: one was a bad permissions grant in the patch tool, the other was a secret left where untrusted code could read it.

The first bug lives in the open-source Codex CLI. In workspace-write mode, Codex is supposed to keep writes inside the workspace folder. A shell command aimed at $HOME gets blocked. But apply_patch, the editing tool the harness gives the agent, hands out write access based on the parent folder of every path in the patch. Mention /tmp and it ends up granting write access all the way to /. That meant a patch could smuggle a write into .zshrc through a symlink into $HOME, then rely on the next terminal session to run it unsandboxed. We called that Overpatch.

The second bug is in the JavaScript tool that Codex Desktop installs. The sandbox itself worked, but the trust boundary did not. Codex writes an [mcp_servers.node_repl] block into the global ~/.codex/config.toml during install, with no opt-in and no switch to disable it. That Rust parent process starts Node inside the Codex sandbox, then splits the JavaScript into two V8 vm contexts: one trusted, one untrusted. The trusted side gets a fresh random token on every run. But both contexts share one heap, and the token is just a string sitting there. Untrusted code can dump the heap, look for UUID-shaped strings, and test them until it finds the right one.

Once it has that token, the rest falls apart. The sandboxed Node process sends requests to the Rust parent as JSON lines over stdout, and the untrusted code can write its own request into that same pipe. The parent then accepts the forged message, checks the token, and carries out the action. In our proof of concept, that meant launching the system open command, which let launchd start an application unsandboxed, outside Codex’s process tree. The same route also exposed Unix sockets, including a Docker daemon socket, and even the tool for editing ~/.codex/config.toml.

Both issues had the same shape: the thing enforcing the boundary was sitting inside the thing it was supposed to contain. That is why Accomplish keeps the whole agent inside a VM instead. The model, bash, git, and whatever they start all live in the guest; real credentials stay out; outbound traffic goes through a host proxy the agent cannot touch. It is a blunt design, and that is the point. If the code can decide for itself what it is allowed to do, the sandbox is already halfway out the door.

My take — AI-written commentary, not fact-checked reporting

This is the oldest security lesson in software: don’t let the prisoner hold the keys and call it policy. Codex tripped over it twice, which is less a surprise than a reminder that “trusted” and “untrusted” code sharing memory is a neat way to build a paper lock. VM-first isolation is boring, and boring is usually what survives contact with clever tools.

Read more about this at: Accomplish

Related stories

The daily briefing

Every AI story that matters, in your inbox by 8am.

TLDRocket reads all relevant sources, removes duplicate coverage, and summarises the day in two minutes. Follow companies and topics for alerts, or get the briefing in Slack. Free, no spam, unsubscribe anytime.