Dependency confusion

SkillAI & models

Dependency confusion / substitution, publish a malicious public package matching an internal name so build systems pull yours. Load on leaked internal package names (npm/PyPI/RubyGems/Maven), package.json/requirements with unknown deps, or private-registry setups. Signals: @scope/internal packages, non-public dep names in manifests, .npmrc/registry config leaks.

Instructions available. Your AI can read the instructions. Execution depends on the setup they require.

Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.

Then ask your AI: use the Dependency confusion skill

What this skill tells your AI

The instructions your AI receives, as published by noorqureshi/sploitagent in skills/web/web-dependency-confusion/SKILL.md and read by ahel’s review.

When it applies

The target builds software using internal package names that aren't published publicly, on an ecosystem (npm, PyPI, RubyGems, Maven, NuGet) where a public registry is also consulted. If you can learn an internal name and publish it publicly, their resolver may fetch your package → RCE in their build/CI.

Why it works

Many package managers, misconfigured, prefer the highest version across all configured registries — public included. Publishing internal-lib@99.0.0 to the public registry can outrank the private internal-lib@1.2.3, so builds pull and execute your code (install scripts run automatically).

Method

  1. Harvest internal names: leaked package.json/requirements.txt/pom.xml, source maps and JS bundles (→ recon-js-analysis), error messages, public repos, .npmrc/registry config.
  2. Confirm the name is unclaimed on the public registry (npm/PyPI/etc.).
  3. Publish a benign PoC package under that exact name with a high version, whose install/postinstall step makes an OOB callback (DNS/HTTP to your collaborator) including hostname/user — no destructive payload. This proves execution if their build pulls it.
  4. Wait for the callback from their build/CI environment → confirms confusion.
  5. Scoped packages: @company/pkg on npm needs the scope unclaimed; note the config that would prevent it.

Gotchas

  • Keep the payload benign and identifiable (your marker only) — you're proving exec, not attacking. Mind program RoE (many bug-bounty programs have specific rules for this).
  • Proper configs (scoped registries, --registry pinning, namespace ownership) prevent it — the finding is the missing control.
  • Take down the package after reporting.

Verify success

An OOB callback from the target's build/CI proving your public package was resolved and its code executed.

References

Alex Birsan "Dependency Confusion"; npm/PyPI scoping & registry-pinning docs.

Signals

GitHub stars
20
Forks
7
Last commit
Sep 2026
Advanced
Item type
skill
Key
web-dependency-confusion
Source
github.com/noorqureshi/sploitagent