Skip to content

Windows: with PATH in the overlay, a bare name like npm now resolves to npm.cmd, so cmd.exe re-parses the arguments and &, |, % in them run as commands #138

Open

Description

@matt-edmondson

What's wrong

ResolveOnSearchPath (RunCommand/RunCommand.cs, around lines 469–498, called from CreateStartInfo around line 416) was added in #137. On Windows, when the name has no extension, it tries every PATHEXT extension in each overlay PATH directory. The default list is .COM;.EXE;.BAT;.CMD, and the first hit wins. So ExecuteAsync("npm", ...) now resolves to C:\nodejs\npm.cmd.

That changes what can run:

This is the same class of bug as BatBadBut (CVE-2024-24576). I worked it out from the code; I have not run it on Windows.

Failure scenario

var options = new CommandOptions { EnvironmentVariables = new Dictionary<string, string?> { ["PATH"] = @"C:\nodejs" } };
await RunCommand.ExecuteAsync("npm", ["install", userInput], handler, options, ct);
// userInput = "x&calc"  → cmd.exe runs `npm install x` and then `calc`

The README presents the argument-vector API as the way to avoid quoting problems, and this breaks that promise without warning. Whether a batch file can be started at all now also depends on whether PATH happens to be in the overlay. Without the overlay, the same call fails with "file not found".

Suggested fix

Pick one of these, and document the choice:

  1. Mirror CreateProcess: when the name has no extension, try only .exe, which keeps the pre-Look a bare executable name up on the overlay PATH [patch] #137 set of startable files.
  2. Skip .bat/.cmd candidates, or throw a clear exception when the only match is a batch file.
  3. If starting batch files by bare name is wanted, escape the arguments for cmd.exe when the resolved file is .bat/.cmd, as Rust did for CVE-2024-24576.

Acceptance: a test on Windows where the overlay PATH holds tool.cmd shows that an argument containing & never runs a second command.

Activity

  1. matt-edmondson commented on Nov 4, 2026

    @matt-edmondson
    ContributorAuthor

    Triage


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions