安全软件
点击放大

<p align="center">
<strong>npx Confusion Scanner</strong><br>
<em>Find unclaimed npm package names in your supply chain before attackers do.</em>
</p>
<p align="center">
<a href="#license"><img src=" alt="License: MIT"></a>
<a href=" src=" alt="Node >= 18"></a>
</p>
---
> Based on the original research by Lupin & Holmes, presented at DEF CON 33.
>
> Read the full paper: npx Used Confusion and It's Super Effective
>
> This tool automates the discovery process described in that research — scanning local codebases, GitHub organizations, and web assets for unclaimed npm package names that are exploitable via npx confusion and dependency confusion attacks.
---
| # | | Se | Description |
|---|---------------|----------|-------------|
| 🔴 | npx Confusion | CRITICAL | An npx <name> in in your package.json scripts points to a package unclaimed on npm. An attacker can register that name and achieve RCE on every de and CI pipeline that runs your scripts. |
| 🔴 | Bin Mismatch | CRITICAL | A scoped package (/pkg) exposes a binary with a different, unscoped name that is unclaimed on npm. Since npm binaries cannot contain /, this mismatch is inherent to scoped packages. |
| 🟡 | Dependency Confusion | HIGH | Private/internal package names (enterprise-scoped packages, file: references) are not registered on the public npm registry. An attacker can publish a package with the same name and hijack installs. |
| 🟠 | Name Clash | MEDIUM | A used package name exists on the public registry but is owned by a different entity — potential typo-squatting or namespace collision worth in. |
npxconfuse automates discovery of these unclaimed names across your entire codebase, GitHub organization, and public-facing web assets.
---
Requirements: Node.js >= 18
---
---
scan — Scan a Local DirectoryWhat it scans:
package.json — scripts (npx in), bin field, dependenciesWith --deep:
*.js, *.mjs, *.cjs) — parses require(), import, and embedded package.json blocksWhat it skips:
node_modules/, .git/, dist/, build/, .next/, co/github — Scan a GitHub OrganizationToken requirements:
repo (private repos) or public_repo (public repos only)web — Scan Web DomainsProbes each domain for:
/package.json, /package-lock.json<script> tagscheck — Direct Package Name Checking---
| Format | Flag | Best For |
|--------|------|----------|
| Table (default) | -o table | Interacti use |
| JSON | -o json | CI/CD pipelines, jq processing |
| CSV | -o csv | Spreadsheets, data analysis |
---
| Option | Description | Default |
|--------|-------------|---------|
| -o, --output <format> | Output format: table, json, csv | table |
| -c, --concurrency <n> | Max parallel registry requests | 20 |
| --timeout <ms> | HTTP timeout (milliseconds) | 10000 |
| --save <filepath> | Sa to file (format auto-detected from extension) | — |
| - | Enable debug logging | false |
Scan-specific options:
| Command | Option | Description |
|---------|--------|-------------|
| scan | --deep | Also parse JS bundles for imports/requires |
| github | --max-repos <n> | Maximum repos to scan | 1000 |
| github | --github-enterprise <url> | GitHub Enterprise base URL | — |
---
| Code | Meaning |
|------|---------|
| 0 | No critical or high findings |
| 2 | Critical findings detected (useful for CI/CD || exit pipelines) |
---
Once npxconfuse identifies unclaimed package names, you'll want to whether those names are actually being pulled in real en. Simply claiming the name and publishing a package is not enough — you need to confirm that the package is being downloaded by real CI pipelines or de.
Publish a harmless package under the unclaimed name that phones home to a server you control. This lets you obser who is pulling the package and from where.
You can use a simple HTTP server, a webhook receiver, or services like:
nc -l or Python HTTP serverExample with a one-liner netcat listener:
Watch your callback logs for incoming requests. Each hit represents a machine that ran npx my-internal-tool or installed the package.
---
When you publish a package to npm, you will see immediate download activity. Most of this is not from real targets — it comes from automated systems that mirror or analyze every new npm package.
| Source | What It Is | Action |
|--------|------------|--------|
| npm CDN / mirror bots | Replication bots from jsDeli, etc. that cache every package | Ignore — these are not your targets |
| Security scanners | Automated tools (Snyk, Socket.dev, etc.) that analyze every new publish | Ignore — they are not real installs |
| Replication services | Third-party registries that mirror npm (e.g. npmmirror.com in China) | Ignore — these are mirrors, not targets |
| npm's own download count | The download counter on npmjs.com includes all mirror/cache traffic | Do not trust download counts as proof |
Real pulls come from actual CI en and de machines. Look for these signals in your callback data:
| Signal | Indicates |
|--------|-----------|
| 🟢 CI hostnames (e.g. github-runner-*, circleci-*, jenkins-*, gitlab-runner-*) | CI pipelines pulling the package |whoami
| 🟢 Corporate hostnames (matches the organization you're testing) | Internal de machines |
| 🟢 Timing alignment — hits coincide with code pushes or scheduled builds | Genuine CI activity |
| 🟢 De usernames in the callback path (from ) | Real de workstations |
| 🟢 Non-standard user agents or IPs from corporate ranges | Authentic internal traffic |
| 🔴 Immediate hits from IPs owned by Cloudflare/Fastly/CDN pro | Likely mirror bots |
| 🔴 Hits at the exact same second as publish | Bots polling the registry feed |
1. Publish your probe package
2. Ignore the first 24—48 hours of activity — this is predominantly bots and mirrors
3. After the initial noise settles, look for patterns that match the target organization's:
- IP ranges
- Hostname con
- CI provider
- Working hours / timezone
4. Only consider hits that correlate with known de activity (commits to repos, CI build triggers)
---
1. Discovery — Finds package.json files and JS bundles glob, GitHub API, or HTTP probespackage.json
2. Extraction — Parses each file with dedicated extractors:
- : npx in scripts, bin field, scoped dependencies with file:/workspace: referencesJS bundles
- : embedded package.json blocks, require() calls, import statements
3. Analysis — Deduplicates names across sources and queries the npm registry in parallel, classifying each name as unclaimed, claimed, private, or error
4. Reporting — Formats results in the chosen output format with se coloring
Se is derived from the finding type, the registry status, and how
npm resolves the dependency at install time.
| Finding Type | Registry Status | Resolution | Se |
|---|---|---|---|
| npx-confusion | unclaimed | registry | 🔴 CRITICAL |bin-mismatch
| | unclaimed | registry | 🔴 CRITICAL |dependency-confusion
| | unclaimed | registry | 🟡 HIGH |dependency-confusion
| | unclaimed | file: / link: | 🔵 LOW |dependency-confusion
| | unclaimed | workspace: | ⚪ INFO |claimed
| Any | | any | 🟠 MEDIUM |private
| Any | | any | ⚪ INFO |
Why resolution matters: only registry resolution can fall back to theworkspace:
public npm registry. The local protocols (, file:, link:,portal:) resol the local filesystem and fail closed when their
target is missing — they ne the registry. An unclaimed name behind a
local protocol is a hygiene issue, not an exploitable install-time .
When a name is declared with more than one protocol across files, the riskiest
protocol wins (e.g. workspace:* in one file and ^1.0.0 in another isregistry
treated as ). Each finding reports both resolution (worst case) andresolutions (all observed).
---
in your npm scriptsnpxconfuse detects both my-build-tool and the unscoped binary name of /custom-linter if they're unclaimed on npm.
If /internal-auth is not registered on the public npm registry, an attacker can publish a malicious package with the same name.
If returns your production manifest, an attacker can extract your internal package names. npxconfuse web helps you find this exposure first.
---
This tool operationalizes the class described by Lupin & Holmes in their DEF CON 33 research:
Key concepts from the research:
cannot find a binary in ./node_modules/.bin/, it falls back to fetching from the public npm registry. If that name is unclaimed, an attacker can register it., so /pkg must expose an unscoped binary name — creating a natural mismatch exploitable for package takeover./--no flags with npx, configure scope-to-registry mappings via .npmrc, and audit your package.json scripts for unregistered npx targets.---
Contributions are welcome! Areas that particularly need help:
---
MIT — see LICENSE file.
---
If you discover a in npxconfuse` itself, please open an issue or submit a PR responsibly. Do not publish the publicly before a fix is a.
开发语言:JavaScript
Star 数:17
该项目属于安全软件方向的开源资源,代码结构清晰,适合安全研究人员学习参考。项目围绕npx confusion vulnerability scanner展开,提供了可运行的实现,对理解相关安全机制、工具原理与攻防技术具有较高的研究价值。
从技术实现角度看,此类项目的核心在于对底层原理的深入理解与工程化落地。开发者在研究过程中可以结合官方文档与社区讨论,梳理项目的初始化流程、核心模块职责与数据流转,逐步掌握其中的技术细节与设计思路。
1. 下载源码压缩包,解压到本地环境。
2. 根据项目类型准备对应的运行环境与依赖。
3. 按照 README 中的步骤完成配置与部署。
4. 在隔离的测试环境中运行验证,避免影响生产系统。
本资源来源于开源社区,仅供安全研究、技术学习与合法授权范围内的攻防演练使用,请勿用于任何非法或侵害他人权益的用途。使用本项目产生的一切后果由使用者自行承担。
| 资源标题 | npxconfuse - npx confusion vulnerability scanner |
| 所属分类 | 安全软件 |
| 发布作者 | admin |
| 发布时间 | 2026-10-05 22:55:48 |
| 下载权限 | 免费下载 |
| 附件数量 | 2 个下载链接 |
| 浏览次数 | 315 |
| 讨论数量 | 0 |
| 主题状态 | 正常讨论中 |