Vulnerabilities

What is Dependency Confusion?

Dependency confusion is a supply chain attack where a malicious public package with the same name as a private internal package causes package managers to install the malicious version.

By the Hyrax team·4 min read·May 1, 2026
TL;DR
  1. 1.Definition
  2. 2.How Dependency Confusion Works
  3. 3.Why Package Managers Are Vulnerable
  4. 4.Impact
  5. 5.Prevention

Definition

Dependency confusion — also called a namespace confusion attack — is a supply chain attack that exploits how package managers resolve dependencies when both public and private package registries are configured. When an attacker publishes a malicious package to a public registry (npm, PyPI, RubyGems) using the same name as a private internal package, and the package manager is configured to check public registries first or alongside private ones, it installs the malicious public package instead of the legitimate internal one.

Security researcher Alex Birsan demonstrated this attack in 2021, successfully compromising build systems at Apple, Microsoft, Shopify, and 30+ other companies through this technique. It earned him over $130,000 in bug bounties.

How Dependency Confusion Works

  1. A company uses a private npm registry to host internal packages, e.g. @acme/auth-utils.
  2. An attacker discovers the internal package name (from package.json files in public repos, job listings, blog posts, or leaked code).
  3. The attacker publishes a package with the same name (@acme/auth-utils) to the public npm registry, using a higher version number than the internal package.
  4. When a developer runs npm install, the package manager resolves to the higher-versioned public package instead of the internal private one.
  5. The malicious package executes attacker-controlled code in the build environment.

Why Package Managers Are Vulnerable

Package managers like npm, pip, and gem are designed to resolve to the highest available version when multiple sources are configured. When a developer's .npmrc lists both a private registry and falls back to the public one, a higher-versioned public package wins the resolution race. This behavior is by design for legitimate use cases but is exploitable for dependency confusion.

Impact

Dependency confusion attacks occur at build time, in CI/CD systems, and in developer environments. A compromised package can:

  • Exfiltrate environment variables including CI/CD secrets, cloud credentials, and API keys
  • Execute arbitrary code on developer machines or build servers
  • Modify build artifacts to introduce backdoors into deployed software
  • Pivot from developer machines to internal networks

Prevention

Scope all private packages

Use scoped package names (@company/package-name) and configure the private registry as the authoritative source for that scope. Npm, pip, and Cargo all support scope-to-registry mapping that prevents public registry fallback for private packages.

Pin exact versions and use lockfiles

Lockfiles (package-lock.json, poetry.lock, Gemfile.lock) pin exact package versions and their checksums. Changes to the resolved package — including substitution by a confused dependency — will cause the lockfile check to fail.

Verify package integrity

Configure package managers to verify checksums against the expected values. npm verify-signatures and pip hash checking provide integrity verification that catches substituted packages.

Namespace reservation

Register private package names on public registries as placeholder packages (with install scripts that immediately error). This prevents attackers from registering your package names on public registries.

Dependency Confusion and Autonomous Code Governance

Hydra audits dependency configuration files (package.json, .npmrc, pyproject.toml, requirements.txt) for dependency confusion risks: unscoped private package names, registry configurations with public fallback for private packages, and missing lockfile integrity verification. Hydra cross-references internal package names against public registry availability and flags names that could be registered by an attacker. Configuration fixes add proper scope-to-registry mappings and integrity verification settings.

Frequently Asked Questions

How do attackers find private package names to target?

Multiple discovery methods: GitHub/GitLab searches for package.json files containing private registry URLs, job postings that mention internal tools, leaked or accidentally public repositories, error messages in public CI/CD logs, and simply guessing common naming patterns (company-utils, company-auth, company-sdk).

Does using a private registry prevent dependency confusion?

A private registry alone does not prevent it. The vulnerability arises from the combination of a private registry and public registry fallback. Prevention requires scope-based registry mapping or explicit configuration that disallows public registry fallback for private package namespaces.

Is dependency confusion the same as typosquatting?

No. Typosquatting involves registering packages with names similar to popular packages (reqeusts instead of requests) to catch typos. Dependency confusion targets the exact name of a known internal package and relies on version resolution logic, not typos. Both are supply chain attacks but through different mechanisms.

Stop flagging. Start fixing.

Hyrax reviews your pull requests, remediates issues autonomously, and closes the ticket.

Join the waitlist