Repository navigation
Conversation
martinrrm
marked this pull request as ready for review
October 1, 2026 18:18
martinrrm
marked this pull request as draft
October 1, 2026 18:18
martinrrm
force-pushed
the
martinrrm/fix-powershell-prefix-injection
branch
from
October 28, 2026 18:20
b2fca96 to
51c2bf8
Compare
Launch the CLI through a native process instead of evaluating executable and CLI paths as PowerShell source, and reject project-level prefix settings so repository config cannot redirect CLI selection. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3e53db77-0fe4-4320-8ada-f2962ddd303c
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3e53db77-0fe4-4320-8ada-f2962ddd303c
There was a problem hiding this comment.
🟡 Changes recommended
Expanded configuration keys and project-controlled user/global config paths still bypass prefix filtering, allowing repositories to redirect CLI selection.
3 open issues
What changed in this PR
This PR hardens npm and npx’s PowerShell launchers by keeping executable paths out of evaluated source while preserving argument syntax and native exit codes. It also filters direct project-level prefix settings during configuration loading.
Changes:
- Replace
Invoke-Expressionwith variable-based script blocks executed in the wrapper scope. - Ignore direct project
prefixentries while retaining the prohibited-setting error. - Add regression coverage for special-character paths, PowerShell syntax, exit codes, and prefix precedence.
| File | Description |
|---|---|
workspaces/config/test/index.js |
Assert that project prefix settings do not affect configuration precedence. |
workspaces/config/lib/index.js |
Remove direct project prefix entries before loading configuration. |
test/bin/windows-shims.js |
Expand shim regression cases and update PowerShell process invocation. |
bin/npx.ps1 |
Invoke npx through a script block that references paths via variables. |
bin/npm.ps1 |
Invoke npm through a script block that references paths via variables. |
Review effort: Max
Ignore project configuration when selecting the global CLI. Reject expanded project prefix keys while preserving raw entries for config saves. Isolate the Windows test environment and cover prefix sources, argument syntax, entry modes, and native exit codes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8a0c2316-9385-4f0a-931e-cb9c15c425c5
martinrrm
force-pushed
the
martinrrm/fix-powershell-prefix-injection
branch
from
November 3, 2026 20:16
70d7cc4 to
0d07dc1
Compare
Compare saved INI data instead of assuming LF line endings. Read one complete piped input line without waiting for EOF under coverage, and bound those subprocess checks so failures report promptly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8a0c2316-9385-4f0a-931e-cb9c15c425c5
Use controlled native CLI fixtures to verify npm and npx shim input and argument forwarding without npm exec or run-script consuming stdin. Bound the fixture child itself so a missing line reports a failure instead of leaving inherited pipes open. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8a0c2316-9385-4f0a-931e-cb9c15c425c5
Disconnect unused host stdin and verify multiline pipeline input, trailing spaces, and argument forwarding without terminating the native fixture mid-stream. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8a0c2316-9385-4f0a-931e-cb9c15c425c5
Run every PowerShell host non-interactively with unused stdin disconnected, and report command timings to expose CI process stalls. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8a0c2316-9385-4f0a-931e-cb9c15c425c5
Allow coverage-enabled Windows shim tests to finish their sequential shell invocations. Bound each PowerShell command independently; TAP file-local overrides cannot extend the runner subprocess deadline. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8a0c2316-9385-4f0a-931e-cb9c15c425c5
| conf.raw = obj | ||
| outer: for (const [key, value] of Object.entries(obj)) { | ||
| const k = envReplace(key, this.env) | ||
| if (where === 'project' && k === 'prefix') { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
prefixbefore project configuration is loaded, so a repository.npmrccannot redirect CLI selection.Regression coverage
prefixis logged as prohibited but cannot affect the effective prefix.Validation
@npmcli/configtests, lint, and postlint pass locally.Refs github/npm#15799, finding CLI-CROW-CMD-002.
Draft intentionally while the refreshed cross-platform CI matrix completes.