highCWE-830A06:2021

Dependency Confusion

Private internal packages without a scope prefix can be hijacked by publishing a higher-versioned public package with the same name.

How It Works

npm resolves unscoped package names by checking the public registry first if you're not explicit. If your company has a private package called 'internal-utils' at version 1.0.0, an attacker publishes 'internal-utils' v9.9.9 on the public registry and npm installs the public one instead — with the attacker's code inside.

Vulnerable Code
// BAD: unscoped private package name is vulnerable to confusion attacks
{
  "dependencies": {
    "internal-utils": "1.0.0",
    "company-auth": "2.1.0"
  }
}
Secure Code
// GOOD: always scope private packages to your organization
{
  "dependencies": {
    "@mycompany/internal-utils": "1.0.0",
    "@mycompany/company-auth": "2.1.0"
  }
}

Real-World Example

In 2021, security researcher Alex Birsan published a paper demonstrating dependency confusion attacks against Apple, Microsoft, PayPal, Uber, and 33 other companies. Microsoft paid him $40,000 in bug bounties for the disclosure.

How to Prevent It

  • Always scope private packages with your organization name (@yourcompany/package-name)
  • Configure your npm client to always resolve scoped packages from your private registry
  • Add your organization scope to your .npmrc to prevent public registry fallback
  • Audit package.json files for unscoped internal package names

Affected Technologies

Node.jsPython

Data Hogo detects this vulnerability automatically.

Scan Your Repo Free

Related Vulnerabilities