diff --git a/src/pentesting-web/dependency-confusion.md b/src/pentesting-web/dependency-confusion.md index 34b5903fcb6..79458c0276d 100644 --- a/src/pentesting-web/dependency-confusion.md +++ b/src/pentesting-web/dependency-confusion.md @@ -28,6 +28,34 @@ If your project references a library that isn’t available in the private regis Developers frequently leave versions unpinned or allow wide ranges. When a resolver is configured with both internal and public indexes, it may select the newest version regardless of source. For internal names like `requests-company`, if the internal index has `1.0.1` but an attacker publishes `1.0.2` to the public registry and your resolver considers both, the public package may win. +### Related pattern: `npx` binary/package-name confusion + +`npx ` is also a **name-confusion execution sink**. If no explicit `--package` is provided, npm first tries to resolve `` as a binary from the local `node_modules/.bin`, global bins, local/global installed packages, and the npx cache. If none of those checks succeed, npm treats the original binary name as the package name, installs it into `~/.npm/_npx//`, prepends that cache's `node_modules/.bin` to `PATH`, and executes it. In CI or non-TTY contexts, npm assumes `--yes`, so the install path is even easier to reach automatically. + +Why this is exploitable: +- **Binary names and package names do not need to match.** A command may be `binary_name` while the real package is `@company/package-name`. +- **Scoped/private packages increase the gap.** The package can be scoped, but the exposed `bin` name is unscoped. +- **Exploitability is context-dependent.** `npx binary_name` may be safe inside the project root where the real binary exists, but unsafe in CI, in a clean workspace, outside the repo root, or in agent automation where `node_modules/.bin` is absent. + +Typical recon sources: +- `package.json` scripts containing `npx ` +- READMEs and onboarding docs +- CI/CD workflows +- bundled manifests leaked in frontend assets +- AI-agent tool definitions that shell out through `npx` + +Practical abuse pattern: +1. Find `npx ` where the intended tool actually comes from another package. +2. Check whether `` exists as a public npm package. +3. If the public name is unclaimed, register it and expose the expected command via the package `bin` field. +4. Wait for execution in a context where the legitimate local binary is missing; npm will fetch the attacker-controlled package into `~/.npm/_npx/` and run it. + +Defensive notes specific to this pattern: +- Prefer **explicit package resolution**: `npx --package=@company/package-name binary_name` or `npm exec --package=@company/package-name -- binary_name`. +- Claim public npm names that match internal/private binaries, especially for scoped packages. +- Treat CI/non-TTY warnings about missing packages that "will be installed" as security events. +- Monitor unexpected cache installs under `~/.npm/_npx/`. + ### Related pattern: compromise of a legitimate package release Dependency confusion is not the only way to get install-time execution. If an attacker compromises the maintainer account or publishing token of a legitimate package, they can publish a malicious version of the real package and obtain code execution on every machine that installs it. @@ -384,6 +412,10 @@ These controls do **not** replace lockfiles or trusted publishing, but they redu - [https://docs.npmjs.com/trusted-publishers/](https://docs.npmjs.com/trusted-publishers/) - [https://docs.npmjs.com/generating-provenance-statements](https://docs.npmjs.com/generating-provenance-statements) - [https://docs.npmjs.com/cli/v11/using-npm/changelog/](https://docs.npmjs.com/cli/v11/using-npm/changelog/) +- [npm exec | npm Docs](https://docs.npmjs.com/cli/v11/commands/npm-exec/) +- [npm/cli v11.15.0 libnpmexec index.js](https://github.com/npm/cli/blob/v11.15.0/workspaces/libnpmexec/lib/index.js) +- [npm/cli v11.15.0 file-exists.js](https://github.com/npm/cli/blob/v11.15.0/workspaces/libnpmexec/lib/file-exists.js) +- [npx Used Confusion and It’s Super Effective](https://www.landh.tech//blog/20260521-npx-used-confusion-and-its-super-effective) - [https://pnpm.io/settings](https://pnpm.io/settings) - [https://bun.sh/docs/runtime/bunfig](https://bun.sh/docs/runtime/bunfig)