Dependency Confusion

Updated Sep 29, 2026

Dependency confusion is a software supply-chain attack that causes a build or installation to retrieve an unintended package with a trusted dependency name. It exploits ambiguous package sources, namespace collisions, or resolution priority. A vibe-coded software audit checks registries, scopes, lockfiles, and build configuration for this ambiguity.

Dependency confusion occurs when a package manager has more than one possible source for a dependency name and selects an unintended package. The application asks for a familiar name, but registry or resolution rules direct the installation to code controlled outside the expected source.

How ambiguous resolution arises

An organization may publish internal packages to a private registry while also allowing access to a public registry. If the same unscoped name can exist in both places, the package manager needs a rule for choosing between them. Version preference, source order, cached metadata, or configuration can influence the result.

The weakness sits in dependency resolution, not in the application import statement. A correct-looking import can lead to a different artifact when the build runs in another environment or resolves the graph again.

Configuration conditionResulting ambiguityAudit evidence
Private and public registries share namesEither source may satisfy a requestRegistry configuration and package scope
Public versions outrank an internal versionResolver may prefer the public artifactVersion policy and resolution log
Lockfile is missing or ignoredA fresh resolution can choose differentlyBuild command and committed files
Mutable source reference is usedContent can change without a name changeCommit, tag, or digest reference

What a code audit traces

An audit of vibe-coded software starts with the complete list of package sources. It identifies private names, checks whether namespaces or scopes reserve them, and follows how local development, continuous integration, and production builds authenticate to each registry.

The review then checks resolution evidence:

  1. List registries: Record every configured public, private, and proxy source.
  2. Map internal names: Identify packages that must resolve only inside the organization.
  3. Read precedence rules: Determine which source and version wins when names collide.
  4. Inspect lockfiles: Confirm whether builds use committed resolutions and integrity data.
  5. Reproduce safely: Verify the selected source in an isolated build environment.

Controls that remove ambiguity

Package scopes or reserved namespaces tie internal names to an expected registry. Explicit registry mapping prevents a resolver from treating public and private sources as interchangeable. Dependency pinning, committed lockfiles, and artifact integrity checks add evidence that the selected package matches the reviewed one.

Software composition analysis can show which component arrived in a build, but prevention belongs in registry and build configuration. Both are needed: one controls resolution, while the other detects what was actually selected.

Why generated setup still needs review

Generated configuration often follows common package-manager defaults. Those defaults do not know which package names are private or which registry is authoritative for the organization. A build can work repeatedly in one environment while remaining ambiguous elsewhere.

The broader dependency risk review treats source identity as part of the component, alongside its name and version. Establishing that identity is one of the production responsibilities described in vibe coding versus agentic engineering.