Threat Intelligence

Dependency Confusion: Attack Evolution from 2022 to 2026

Alex Birsan's 2021 disclosure named a class of attacks. Four years on, dependency confusion has evolved across registries, tooling, and victim profiles.

Daniel Chen
Senior Researcher
5 min read

Alex Birsan published the original dependency confusion writeup in February 2021 and collected bug bounties from Apple, Microsoft, PayPal, and a long list of others. The technique was elegant: register the name of a company's internal package on a public registry, and package managers configured to prefer the highest version would happily pull the public, attacker-controlled version. Four years later, the class of attacks has not been eliminated. It has fragmented, adapted, and migrated.

This post tracks the evolution and the categories of organization that keep getting caught.

How did the attack work originally, and what changed in 2022?

The original technique exploited the default resolution behavior of npm, pip, and several other package managers when an organization mixed public and private registries in their dependency tree. If an internal package called acme-internal-utils existed only in the private registry, an attacker could publish a higher-versioned acme-internal-utils to the public npm registry, and the resolution algorithm would prefer the public version on the next install. Birsan demonstrated the technique against more than 35 organizations and recovered tens of thousands of dollars in bounties.

The 2022 evolution was the industrialization of the technique. Researchers and attackers built automated tooling to scrape package.json and pip requirements files from public GitHub repositories belonging to large organizations, identify internal-looking dependencies, and squat the corresponding names on public registries en masse. Throughout 2022, npm and PyPI both saw waves of newly registered packages with naming patterns characteristic of internal tooling at named Fortune 500 companies. Most of these were proof-of-concept registrations by researchers, but a meaningful fraction were malicious.

What did the registries and tooling vendors actually do?

The major registries responded with namespace and scoping enforcement. npm scopes, which had existed since 2014, became the canonical defense and adoption accelerated. By late 2023, most enterprise internal packages on npm were scoped under organization-specific prefixes like @acme, and configuration patterns to refuse public-registry resolution for scoped names became standard. PyPI added namespace-style controls more slowly and less completely, and the recommended defense on the Python side has remained explicit index-url pinning in pip configuration plus internal mirroring.

Artifact repository vendors like JFrog, Sonatype Nexus, and the cloud-provider equivalents added explicit dependency-confusion protections, typically called either upstream block lists or exclusive resolution rules. Properly configured, these features ensure that a package name appearing in the internal registry is never resolved from a public upstream. The configuration is straightforward but the deployment fragmentation across large enterprises has been the persistent problem.

Which victim profiles persist in 2026?

Three victim profiles persist in 2026. The first is recently acquired subsidiaries inside a larger parent organization. Acquisition-day infrastructure inherits the acquired company's package configurations, which often pre-date the parent's hardened defaults, and the integration timeline that prioritizes business operations leaves these configurations unaddressed for months. Documented dependency confusion compromises in 2024 and 2025 disproportionately involved recently acquired entities.

The second profile is organizations using polyglot build systems with inconsistent registry configurations across language ecosystems. A team might have hardened their npm configuration thoroughly but left pip, gem, or cargo configurations as defaults, with the same internal package naming patterns visible across the GitHub footprint. Attackers scan opportunistically and the weakest ecosystem becomes the entry point.

The third is internal tooling teams using Maven, Gradle, or NuGet without the same level of scrutiny that the script-language ecosystems received in 2021 and 2022. Several reported incidents in 2025 involved internal Java packages whose names had been squatted on Maven Central. The mechanics differed in detail from the npm case but the underlying configuration mistake was identical.

What does a modern dependency confusion attack look like?

A modern attack chains opportunistic registration with delayed activation. The attacker registers the squatted name, publishes a benign initial version, waits for installation telemetry to confirm a victim has resolved the package, and only then publishes a malicious update. This pattern defeats one-shot install-time scanning because the package looks clean at first install and the malicious behavior arrives later. Detection requires either continuous registry monitoring for behavioral changes in already-installed packages or strict version pinning that prevents automatic upgrade.

Several confirmed 2025 incidents followed this pattern, including a confirmed compromise of a payments-industry company where the attacker waited approximately eleven weeks between initial squat and payload deployment.

What remains underdone in 2026?

What remains underdone is the inventory side of the problem. Most organizations cannot quickly produce a list of every internal-namespace package name in active use across every language ecosystem in their estate. Without that inventory, the registry-level defenses cannot be reliably configured. Programs that have invested in centralized SBOM ingestion across all repositories have a meaningful advantage here because the SBOM tells them what to defend. Programs that rely on per-team configuration have the structural risk that one misconfigured team puts the rest of the organization at risk via shared internal namespaces.

How Safeguard Helps

Safeguard inventories every internal package name across your SBOM corpus and continuously cross-references those names against public registry registrations. Newly registered public packages whose names match your internal patterns surface as a high-priority alert with the affected repositories and services already correlated. Griffin AI watches for the delayed-activation pattern by tracking behavioral baselines on every dependency and flagging post-install changes that diverge from historical norms. Policy gates can block builds that resolve any internal-namespace dependency from a public upstream, turning the dependency confusion class into an enforced configuration rather than a vigilance exercise.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.