openai / openai/codex

Windows execpolicy false positive when Start-Process and an unrelated URL appear in the same PowerShell script

Open
#40,060 19 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug CLI sandbox windows-os
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

What version of Codex CLI is running?

codex-cli 0.146.0

The failure was reproduced on 0.146.0. I also checked the latest stable release, 0.149.0, and the current main branch; both still contain the same relevant classifier logic described below.

What subscription do you have?

Pro

Which model were you using?

gpt-5.6-sol

What platform is your computer?

Microsoft Windows NT 10.0.26100.0 x64 (Windows 11 Professional)

What terminal emulator and version are you using (if applicable)?

Windows Terminal, PowerShell 7.6.3

Codex doctor report

The full report contains private local paths, so the relevant redacted fields are included below. All relevant runtime, config, auth, sandbox, and installation checks were OK; the overall warning was an unrelated update-status warning.

{
  "schemaVersion": 1,
  "overallStatus": "warning",
  "codexVersion": "0.146.0",
  "runtime": {
    "platform": "windows-x86_64",
    "installMethod": "npm"
  },
  "config": {
    "model": "gpt-5.6-sol",
    "modelProvider": "openai"
  },
  "system": {
    "os": "Windows 10.0.26100 (Windows 11 Professional) [64-bit]"
  },
  "terminal": {
    "terminal": "Windows Terminal",
    "powershell": "7.6.3"
  }
}
What issue are you seeing?

On Windows, execpolicy falsely classifies a benign compound PowerShell script as a dangerous URL launch when the script contains both:

  1. a local Start-Process invocation with no URL argument, and
  2. an unrelated Invoke-RestMethod call to an HTTP URL later in the script.

With approval policy never, Codex rejects the command before PowerShell starts:

"C:\Program Files\PowerShell\7\pwsh.exe" -Command '...'
rejected: blocked by policy

The rejection is immediate (Wall time 0.0 seconds). Running the local Start-Process command by itself succeeds, and running the HTTP probe by itself succeeds. Combining them in one PowerShell script triggers the rejection.

This affects a common local-development pattern: start a local application or development server, then poll its loopback health/CDP endpoint until it is ready.

What steps can reproduce the bug?
  1. Run Codex on Windows with approvals disabled, for example:

    codex -a never -s danger-full-access
    
  2. Ask Codex to execute this single PowerShell tool command:

    $process = Start-Process `
      -FilePath "$env:SystemRoot\System32\cmd.exe" `
      -ArgumentList @('/c', 'exit', '0') `
      -WindowStyle Hidden `
      -PassThru
    
    try {
      Invoke-RestMethod `
        -Uri 'http://127.0.0.1:9/health' `
        -TimeoutSec 1
    } catch {}
    
    $process.Id
    
  3. Observe that Codex rejects the entire command with rejected: blocked by policy before pwsh.exe runs.

  4. Execute the Start-Process portion and the Invoke-RestMethod portion as two separate Codex tool calls. Both are allowed, confirming that the combination is what triggers the false positive.

What is the expected behavior?

Execpolicy should only classify Start-Process as a dangerous URL/ShellExecute launch when an HTTP/HTTPS URL is an argument of that Start-Process invocation (or otherwise belongs to the same command expression).

An unrelated URL used by a separate Invoke-RestMethod command should not cause a local executable launch to be rejected.

The truly dangerous case must remain blocked:

Start-Process 'https://example.com'
Additional information

The apparent root cause is in is_dangerous_powershell_words. It computes has_url across the full flattened token list and independently checks whether any token contains start-process:

https://github.com/openai/codex/blob/rust-v0.149.0/codex-rs/shell-command/src/command_safety/windows_dangerous_commands.rs#L36-L52

As a result, the URL and Start-Process token do not need to belong to the same command. The same implementation is still present on main:

https://github.com/openai/codex/blob/main/codex-rs/shell-command/src/command_safety/windows_dangerous_commands.rs#L36-L52

When the heuristic marks the command dangerous and approval_policy is never, the decision becomes Forbidden:

https://github.com/openai/codex/blob/rust-v0.149.0/codex-rs/core/src/exec_policy.rs#L728-L741

A regression test could assert that this is not dangerous:

Start-Process local.exe; Invoke-RestMethod http://127.0.0.1:1234/health

while preserving the existing test that Start-Process 'https://example.com' is dangerous. A robust fix would associate URL arguments with the specific PowerShell command/AST node rather than scanning the whole script token set.

Related PowerShell execpolicy/parser reports, but not duplicates of this false positive:

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.

Research direction

Start in codex-rs/shell-command/src/command_safety/windows_dangerous_commands.rs, especially is_dangerous_powershell_words, and inspect the related decision in codex-rs/core/src/exec_policy.rs. Add a regression for a local Start-Process followed by Invoke-RestMethod, while preserving the dangerous Start-Process 'https://example.com' case. Done means unrelated URLs no longer trigger rejection, including under approval_policy never.

Written by the indexing model from the issue text.

Assessment

Tech stack
powershell, rust
Domain
cli, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.