Windows execpolicy false positive when Start-Process and an unrelated URL appear in the same PowerShell script
Nobody has claimed this yet.
- 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:
- a local
Start-Processinvocation with no URL argument, and - an unrelated
Invoke-RestMethodcall 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?
-
Run Codex on Windows with approvals disabled, for example:
codex -a never -s danger-full-access -
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 -
Observe that Codex rejects the entire command with
rejected: blocked by policybeforepwsh.exeruns. -
Execute the
Start-Processportion and theInvoke-RestMethodportion 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:
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:
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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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