#65864 closed enhancement (fixed)
Build/Test Tools: Avoid npx when running build and test tooling
| Reported by: | adrianmoldovanwp | Owned by: | johnbillion |
|---|---|---|---|
| Priority: | normal | Milestone: | 7.2 |
| Component: | Build/Test Tools | Version: | |
| Severity: | normal | Keywords: | has-patch has-unit-tests fixed-major |
| Cc: | Focuses: |
Description
npx downloads a package and its dependencies from the registry when it cannot find that package locally, then runs the install scripts of every one of them.
Each call is a point where a compromised package can run code during a build.
Build and test tooling invokes five packages through npx, all of them already known and pinnable:
File Command
.github/workflows/reusable-end-to-end-tests.ymlnpx playwright install.github/workflows/reusable-performance-test-v2.ymlnpx playwright installGruntfile.js,qunittasknpx playwright testGruntfile.js,wp-packages:updatetasknpx wp-scriptsGruntfile.js,browserslist:updatetasknpx update-browserslist-db@latest
Replace each call with npm exec --no, which runs an installed binary and fails when the package is missing.
Change History (32)
This ticket was mentioned in PR #13021 on WordPress/wordpress-develop by @adrianmoldovanwp.
5 weeks ago
#1
- Keywords has-patch has-unit-tests added
#5
@
4 weeks ago
- Keywords fixed-major added
Given that this is a Build/Test Tools change with security benefits, I think that it's worth exploring the level of effort required to backport this to old branches.
@desrosj commented on PR #13021:
4 weeks ago
#6
This was committed in r63309. This should have been closed automatically, but seems there is some kind of bug. I opened Core-65892 to look into this.
This ticket was mentioned in PR #13107 on WordPress/wordpress-develop by @adrianmoldovanwp.
4 weeks ago
#7
Backports r63309, already in trunk via #13021, to the 7.0 branch. It replaces the last two npx calls in Gruntfile.js with npm exec --no, which runs an installed binary instead of downloading and installing one.
## Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5
Used for: Checking which hunks of r63309 apply to this branch, editing Gruntfile.js, and verifying that both binaries resolve locally.
This ticket was mentioned in PR #13108 on WordPress/wordpress-develop by @adrianmoldovanwp.
4 weeks ago
#8
Backport of r63309 to the 7.1 branch, already in trunk via #13021. It replaces every npx call with npm exec --no, which runs an installed binary and fails when the package is missing.
## Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5
Used for: Applying the backport, confirming both files match r63309, and running the QUnit suite. I reviewed and tested the result.
This ticket was mentioned in PR #13109 on WordPress/wordpress-develop by @adrianmoldovanwp.
4 weeks ago
#9
This ticket was mentioned in PR #13110 on WordPress/wordpress-develop by @adrianmoldovanwp.
4 weeks ago
#10
This ticket was mentioned in PR #13111 on WordPress/wordpress-develop by @adrianmoldovanwp.
4 weeks ago
#11
This ticket was mentioned in PR #13112 on WordPress/wordpress-develop by @adrianmoldovanwp.
4 weeks ago
#12
Backport of r63309 to the 6.6 branch, already in trunk via #13021: the wp-packages:update and browserslist:update Grunt tasks now call npm exec --no instead of npx, which installs a missing binary and runs its install scripts. It also adds update-browserslist-db to devDependencies, so browserslist:update does not rely on npm hoisting it out of browserslist.
This ticket was mentioned in PR #13113 on WordPress/wordpress-develop by @adrianmoldovanwp.
4 weeks ago
#13
This ticket was mentioned in PR #13121 on WordPress/wordpress-develop by @adrianmoldovanwp.
4 weeks ago
#14
@lancewillett commented on PR #13107:
12 days ago
#17
Committed to the 7.0 branch in https://core.trac.wordpress.org/changeset/63413
@lancewillett commented on PR #13108:
12 days ago
#18
Committed to the 7.1 branch in https://core.trac.wordpress.org/changeset/63414
@lancewillett commented on PR #13110:
11 days ago
#20
Committed to the 6.9 branch in https://core.trac.wordpress.org/changeset/63428
@lancewillett commented on PR #13109:
11 days ago
#22
Committed to the 6.8 branch in https://core.trac.wordpress.org/changeset/63429
@lancewillett commented on PR #13121:
11 days ago
#24
Committed to the 6.7 branch in https://core.trac.wordpress.org/changeset/63430
@lancewillett commented on PR #13112:
11 days ago
#26
Committed to the 6.6 branch in https://core.trac.wordpress.org/changeset/63431
@lancewillett commented on PR #13111:
11 days ago
#28
Committed to the 6.5 branch in https://core.trac.wordpress.org/changeset/63432
@lancewillett commented on PR #13113:
11 days ago
#30
Committed to the 6.4 branch in https://core.trac.wordpress.org/changeset/63433
#32
@
11 days ago
In Gutenberg, I had cleaned up much of the npx usage in these PRs, but there are still some uses there.
- https://github.com/WordPress/gutenberg/pull/81017
- https://github.com/WordPress/gutenberg/pull/81137
I will try to clean up the remaining usages.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
Trac ticket: 65864
npxdownloads a package and its dependencies from the registry when it cannot find that package locally, then runs the install scripts of everything it downloaded. Each call is a point where a compromised package can run code during a build.This patch replaces every
npxcall in the repository withnpm exec --no, which runs an installed binary and fails when the package is missing.update-browserslist-dbis now a devDependency at 1.3.1.browserslistalready required it as^1.2.3, so the lockfile hoists a package that was present and adds none.## Testing instructions
npm ci.npm exec --no -- playwright --version. It prints the installed version and downloads nothing.node_modules/update-browserslist-dband runnpm exec --no -- update-browserslist-db. It fails withnpx canceled due to missing packages and no YES optioninstead of fetching the package. Restore the tree withnpm ci.grunt qunitand confirm the QUnit tests still run.## Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5
Used for: Auditing the
npxcall sites. I reviewed and verified the result, including thenpm exec --nobehavior described above.