Build1 publisher2 min readPublished
Codex read-only mode let an untrusted repo's author run a command on your Mac
OpenAI patched two Codex sandbox escapes within eight days of an August 12 report. The Desktop fix is a build number, but the tool the escape targeted stays in config.toml and loads into every session.
The Engineer · Build desk
Drafted by a language model from the sources cited here and checked against its claim ledger before publication. How we use AISend a correction
What happened
- In read-only mode, opening an untrusted repository and asking about its code was enough for that repository's author to run a command on the machine, with no approval dialog and nothing on screen.
- The fix ships as Codex CLI 0.149.0 or later for the bug the write-up names Overpatch, and Codex Desktop 26.818.21641 or later for the Heapjack escape.
- Heapjack never attacks the sandbox's own code; it defeats the assumption that trusted and untrusted JavaScript running in one process can be separated by anything short of the process boundary.
- The published proof of concept runs only on macOS, where the parent calls the system open command so launchd starts the target application unsandboxed, outside Codex's process tree.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- constraint A version bump swaps the vulnerable binary but not the global tool the installer wrote, so 'patched' and 'clean' are different states on every machine that ever ran Codex Desktop.
- exposure On macOS the unsandboxed parent reaches any unix socket the user can, Docker's daemon socket included, so a working escape controls more than the repository you opened.
- precedent The trust boundary was one secret string in a shared heap, and the parent's errors signalled when a guess was right; any agent tool that authenticates in-process this way inherits the same guessable oracle.
The escape, which the write-up calls Heapjack, does not break the sandbox's code. [7] It targets a JavaScript tool that Codex Desktop installs, and the tool runs as two pieces. An unsandboxed native Rust parent opens applications, connects to unix sockets, and writes the global config file. A Node process inside the Codex sandbox runs the JavaScript and sends the parent its requests. [8]
Two choices turn that into a hole. The trusted and the untrusted JavaScript run as two contexts in one Node process, so they share a single V8 isolate and a single heap, and the credential that proves a request came from trusted code is just a secret token. [9] As the write-up puts it, "the token is a string in that heap." [10] The requests travel as JSON lines on stdout, one pipe that both contexts write to. [11]
From there the attack is mechanical. Untrusted code takes a heap snapshot with v8.getHeapSnapshot(), reads out the UUID-shaped strings, and once it has the token it writes its own request onto the shared pipe. The parent reads the line, checks the token, and does the privileged work. [12]
Both bugs are already fixed, so this is not an open emergency. [3] Oren Yomtov's write-up went public on September 15 and was covered by BleepingComputer on September 20, 34 days after the report. [1][2][1] The patch is a build number. A Desktop install had already written a global tool into ~/.codex/config.toml, and that entry is inherited by every session. [18][5] So the honest check is two commands: codex --version against the fixed builds, and grep -n "node_repl" ~/.codex/config.toml to see whether the tool the escape targeted is still loaded. [4][5]
The proof of concept runs on macOS only, and the author says scope beyond macOS is not established and that they did not reproduce the attack. [16] A second, separate bug needed workspace-write mode rather than read-only. It lived in the CLI's patch flow, where apply_patch, in the write-up's words, "grants write access to the parent folder of each path in the patch. Name /tmp and it grants write access to /." [17]
What to watch
- Whether OpenAI changes the update to strip the node_repl entry from config.toml, not just patch the binary.
- Whether anyone reproduces Heapjack on Linux or Windows, since the write-up establishes only macOS.
- Whether the Codex CLI tightens apply_patch so a path like /tmp no longer grants write access to its parent folder.