A branch name with a semicolon in it was enough to pull a GitHub OAuth token out of OpenAI's Codex, according to a DevOps.com write-up of a critical flaw that BeyondTrust's Phantom Labs disclosed in March. OpenAI has fixed it. For teams wiring agents into their delivery pipelines, the bug matters less than the token. Its scope decided how far a single injected command could reach.
The mechanism
When Codex created a task container, it passed the target branch name into a shell command without sanitizing it first. Bash interpreted characters such as ;, &&, |, $() and backticks as shell syntax rather than as part of a name.
The proof of concept was short. Set the branch to main, add a semicolon to end the intended git command, then append a second command that writes the output of git remote get-url origin to a file. That remote URL held the GitHub OAuth token in cleartext. The researchers then asked the agent, in the prompt, to read the file back. Codex read it, and the token came back in the agent's own task output.
The write-up says the flaw reached every Codex surface: the ChatGPT web interface, the CLI, the SDK and the IDE extension. Researchers confirmed it could be automated to compromise multiple users sharing a repository. OpenAI spent roughly six weeks on iterative hardening before the issue was classified Critical and cleared for public disclosure.
Blast radius is a provisioning choice
The DevOps.com piece describes each wired-up agent as a new privileged identity. The agent clones a real repository and authenticates with a real GitHub credential, but it gets less scrutiny than a human with the same access would. A token limited to one branch of one repo turns this injection into an inconvenience. A token with broad organizational access turns it into an org-wide GitHub compromise that started in a coding assistant.
The article backs this with survey data. Teleport's 2026 State of AI in Enterprise Infrastructure Security report, built on interviews with 205 CISOs and security architects, found that organizations over-provisioning AI systems see 4.5 times more security incidents than those enforcing least privilege. In the same report, 70% said they give AI agents more access than a human doing the identical task, and 67% still use static credentials for AI systems. Both Teleport and Gravitee, whose separate survey the article also cites, sell access and security products in this space. Treat the figures as directional.
Hardening the input path
Git allows ;, $, parentheses, &, | and backticks in ref names, so git check-ref-format will not reject this payload. The agent harness has to do it. The article's list of untrusted fields covers branch names, file paths, commit messages and ticket titles. Any of them becomes command injection once it reaches a subprocess unsanitized.
The narrowest fix is to stop building shell strings. If a shell is unavoidable, allowlist the characters, reject anything that looks like an option, and quote the value:
# $BRANCH and $REPO_URL arrive from the task request; treat them as hostile
case "$BRANCH" in
-* | *[!A-Za-z0-9._/-]*) echo "rejecting branch name" >&2; exit 1 ;;
esac
git clone --branch "$BRANCH" --single-branch "$REPO_URL" workspace
Moving the token is not enough
Moving the token out of the remote URL and into a credential helper or a git config header changes the file that holds it. Any command running as the agent's user can still read it. What limits the damage is scope and lifetime. The article's checklist:
- Scope the credential to the task, not to the developer who configured the agent.
- Prefer short-lived, single-use credentials over static tokens, so a theft is limited to one task.
- Ask for actual visibility into what the agent's credential can do right now, as a list of repos and scopes, not a policy document.
CI has already seen this bug class
None of this is new to pipeline operators. GitHub's Actions hardening guidance has long warned against interpolating attacker-controlled values such as github.head_ref or pull request titles directly into run: scripts, and it recommends passing them through an environment variable. GitHub App installation tokens can be restricted to selected repositories and permissions, and they expire after an hour. GitLab's CI_JOB_TOKEN is valid only while its job runs. OIDC federation replaces stored cloud keys with per-job tokens.
Agent harnesses do not inherit any of that by default. The Codex sanitization bug is closed. How far the next leaked agent token reaches depends on how the agent was provisioned, and that decision belongs to whoever configured it.
Top comments (0)