• Agents
  • Docs
  • Pricing
  • Blog
Log in
Get started

Security for apps built with AI. Paste a URL, get a report, fix what matters.

Product

  • How it works
  • What we find
  • Pricing
  • Agents
  • MCP Server
  • CLI
  • GitHub Action

Resources

  • Blog
  • Docs
  • FAQ
  • Glossary

Security

  • Supabase Security
  • Next.js Security
  • Lovable Security
  • Cursor Security
  • Bolt Security

Legal

  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • Imprint
© 2026 Flowpatrol. All rights reserved.
Home/Glossary/Dependency Confusion
CWE-427

Supply Chain Attack (Dependency Confusion)

Dependency confusion is a supply chain attack where an attacker publishes a malicious package to a public registry (like npm) using the same name as a private, internal package. When a build tool resolves dependencies, it may prefer the public version over the private one — silently installing and executing attacker-controlled code. It is classified under CWE-427 (Uncontrolled Search Path Element).

What is Dependency Confusion?

Your company has an internal package called analytics-utils. It lives in your private registry, and a dozen services depend on it. An attacker notices the name isn't claimed on npm — so they publish their own analytics-utils with a higher version number and a postinstall script that phones home.

Next time someone runs npm install or your CI pipeline builds, the package manager sees two sources for analytics-utils: your private registry and the public npm registry. Many configurations default to the public registry, especially when the public version has a higher semver. The attacker's code runs automatically during install.

This isn't hypothetical. In 2021, security researcher Alex Birsan used this exact technique to execute code inside Apple, Microsoft, and Tesla build systems. The attack requires zero interaction from the victim — it exploits how package managers resolve names across multiple registries.

How does Dependency Confusion work?

The attack targets the gap between private and public package registries. If your package.json references an unscoped package name that exists only in your private registry, an attacker can squat that name on the public registry.

Here's a typical vulnerable setup:

Vulnerable — unscoped private package name
// package.json
{
  "name": "my-app",
  "dependencies": {
    "analytics-utils": "^2.0.0",
    "billing-core": "^1.3.0",
    "react": "^18.2.0"
  }
}

// No .npmrc — default registry resolution
// npm will check the public registry first
Fixed — scoped packages + registry pinning
// package.json
{
  "name": "my-app",
  "dependencies": {
    "@company/analytics-utils": "^2.0.0",
    "@company/billing-core": "^1.3.0",
    "react": "^18.2.0"
  }
}

// .npmrc — pin scoped packages to private registry
@company:registry=https://npm.company.internal/
//npm.company.internal/:_authToken=${NPM_TOKEN}

Why do AI tools generate Dependency Confusion vulnerabilities?

AI code generators focus on making things work. When they scaffold a new package or add a dependency, they rarely think about registry resolution or namespace squatting — because the training data doesn't either.

  • AI doesn't know your infrastructure. It has no idea whether <code>analytics-utils</code> is a private package in your org or a public one. It generates the simplest import path and moves on.
  • Unscoped names are the default. Most tutorial code and open-source examples use unscoped package names. AI learned from those patterns and reproduces them.
  • .npmrc files are treated as boilerplate. AI tools rarely generate registry configuration. When they do, they often skip the scope-to-registry mapping that prevents confusion attacks.

The dangerous part: this vulnerability is invisible in code review. The <code>package.json</code> looks normal. The attack happens at install time, in the gap between what your code says and how your toolchain resolves it.

Common Dependency Confusion patterns

Unscoped internal packages

Private packages without an @scope prefix — trivially squattable on the public registry.

Missing .npmrc registry config

No scope-to-registry mapping, so the package manager falls back to the public registry for everything.

Wildcard version ranges

Using * or very broad ranges means a higher-versioned malicious public package always wins.

CI pipelines without lockfile enforcement

Running npm install instead of npm ci in CI lets the resolver pick up new (malicious) versions.

How Flowpatrol detects Dependency Confusion

Flowpatrol inspects your application's dependency setup for the patterns that make confusion attacks possible:

  1. 1Scans for unscoped internal packages that could be squatted on public registries.
  2. 2Checks registry configuration to verify that .npmrc or equivalent files pin private scopes to internal registries.
  3. 3Flags missing lockfile enforcement in build configurations where npm ci or equivalent isn't used.
  4. 4Reports with fix instructions — the exact .npmrc config and scope changes needed to lock it down.

Supply chain attacks are hard to catch after the fact. Flowpatrol finds the configuration gaps before an attacker does.

Related terms

Untrusted Data Deserialization (Insecure Deserialization)Hard-Coded Credentials (API Key Exposure)Missing Audit Trail (Insufficient Logging)

Check your supply chain.

Flowpatrol scans your app for dependency confusion risks, exposed configs, and supply chain gaps. Paste your URL.

Try it free