[RIP-SEC] Command safe-list keys on the executable basename, so `./cat` (an attacker-controlled file) is auto-approved without a prompt under `UnlessTrusted`

Open
#37,078 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
68/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
rust
Domain
security

Research direction

Start with executable_name_lookup_key in codex-rs/shell-command/src/command_safety/is_dangerous_command.rs, then trace render_decision_for_unmatched_command in codex-rs/core/src/exec_policy.rs. Reproduce the listed bare and path-qualified commands under UnlessTrusted and add regression coverage. Done means path-qualified argv[0] no longer receives the trusted-command approval while bare safe commands retain their intended behavior.

Written by the indexing model from the issue text.

Description

bug CLI safety-check sandbox

Summary

The "known-safe" command list — which, under AskForApproval::UnlessTrusted, lets a command run
without prompting the user — is matched against the executable's basename only. So any path
spelling of a name on the list (./cat, /tmp/evil/cat, a PATH-shadowed cat) classifies as the
trusted cat and is auto-approved, even though a different file actually executes.

Where

  • codex-rs/shell-command/src/command_safety/is_dangerous_command.rsexecutable_name_lookup_key
    returns Path::new(raw).file_name() (basename only; on Windows it also lowercases and strips
    .exe/.cmd/.bat/.com).
  • codex-rs/core/src/exec_policy.rsrender_decision_for_unmatched_command returns
    Decision::Allow (no prompt) when is_known_safe && !used_complex_parsing && approval_policy == UnlessTrusted.
  • Present on current main.

Reproduction

is_known_safe_command returns true for ["./cat", ...], ["../cat", ...],
["/tmp/evil/cat", ...], ["a/b/cat", ...] — the same as bare ["cat", ...] — while ["./payload"]
returns false. So an attacker who stages ./cat (writable under workspace-write) and has it invoked
gets the silent auto-approve that an honestly-named ./payload would not.

Impact

Under UnlessTrusted, an attacker-controlled binary whose basename matches the safe-list bypasses the
approval prompt the user relies on. The command still runs inside the active sandbox — this is an
approval-desync, not a sandbox escape.

Suggested fix

Only honor the safe-list for a bare command name (no /), or resolve argv[0] against PATH/cwd and
confirm it maps to the expected system binary before treating it as known-safe; require a prompt for
any path-qualified argv[0].

Prior art / not a duplicate

Same family as the "GitPwned" allowlist finding and CVE-2025-54558 (ripgrep --pre/-z), but those
trust the ARGUMENTS of an allow-listed command; this is basename-vs-path on argv[0] (a distinct
mechanism — the GitPwned writeup states basename spoofing was not their vector).


Found with the rust-in-peace pipeline
(AI-assisted Rust vulnerability research).

Dominant language
Rust
Stars
125k
Forks
19.5k
Avg merge
1m
Merged PRs (30d)
1k

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from openai/codex

All issues in openai/codex

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.