Dependency confusion turned five years old in February 2026. The original disclosure showed that a researcher could earn bug bounties from major technology companies simply by registering public package names that matched internal package names referenced in their build configurations. Five years later, the attack still works, the tradecraft has evolved, and the defensive picture is uneven enough that incidents continue to land in the security press almost every quarter.
This post looks at the five-year arc, what has changed, what has not, and where the remaining risk lives.
The original attack, briefly
The mechanic is straightforward. Most public package registries default to resolving a package name from the public index even when an internal package of the same name exists. If a build configuration references both a public registry and an internal one without strict scoping, and the public registry happens to have a higher version of a name that the build expects to come from internal infrastructure, the public version wins.
Attackers exploited this by reading public artifacts (Dockerfiles, GitHub repositories, leaked CI logs, JavaScript bundles, public Maven manifests) for internal-looking package names, registering those names publicly with a high version number, and watching for build telemetry. In 2021 this approach earned the original researcher more than $130,000 in bounties across companies that included some of the most security-mature organizations in the world.
What changed between 2021 and 2024
The immediate response in 2021 and 2022 was registry-side and tooling-side mitigations. Major registries added scoped namespaces and private organization features. Package managers added flags and configuration for stricter index resolution. Internal artifact repositories pushed customers toward namespace-locked policies.
Adoption was uneven. Large organizations with dedicated platform teams generally adopted the new patterns by 2023. Mid-sized organizations were a mixed bag. Small organizations, including many fast-growing startups, kept default configurations because the defaults were friendly and the security implications were not visible until something went wrong.
Tooling vendors added detection. Static analysis of build configurations could flag risky resolution patterns. Pre-build resolution checks could warn when a package about to be installed came from a different source than expected. These tools spread, but they were opt-in.
By 2024, the original simple form of dependency confusion was meaningfully harder to execute against well-configured organizations. New variants started appearing.
The 2024 to 2026 evolution
Three evolutions defined the second wave.
The first was multi-ecosystem expansion. Initial coverage focused on npm and PyPI. By 2024, confirmed dependency confusion incidents had been reported in private RubyGems, internal NuGet feeds, internal Maven repositories, and even container image registries where private and public images shared name fragments. The mental model of "public versus private package name collision" generalized to anywhere a name resolution layer existed.
The second was metadata mining at scale. Earlier attacks relied on humans reading public Dockerfiles or repository configurations. By 2024, automated systems were continuously crawling public sources for internal-looking package references, building dictionaries of organization-to-internal-name mappings, and pre-registering the high-value names without waiting for a specific bounty target. This created a kind of squatter inventory that activates whenever a corresponding organization makes a build mistake.
The third was bait packages disguised as legitimate utilities. Rather than publishing an obvious confusion attack, modern attackers publish a package that looks plausibly useful, with a real README, real documentation, and even real benign functionality. The malicious behavior triggers only when the package detects it has been pulled into an internal CI environment matching specific characteristics. The bait approach reduces detection rates because the package looks fine in casual review.
The 2025 and 2026 incident pattern
Public incident reports from 2025 through Q1 2026 show roughly fifteen confirmed dependency confusion compromises landing in the security press, with many more disclosed only privately to bug bounty programs or via insurance carriers.
The compromised organizations skew toward two categories. Large organizations with sprawling internal package ecosystems, where a single misconfigured project among thousands provides an entry point, account for roughly half. Fast-growing mid-sized organizations whose platform teams have not yet hardened the build path account for the rest.
The damage profile has matured. Earlier dependency confusion incidents often ended at "reverse shell from a CI runner," which was bad but contained. Modern incidents extend further because the modern CI runner has more privileges. Cloud credentials, signing keys, deployment tokens, and access to source repositories are now routinely exposed to a runner, and a five-minute foothold can yield material that supports follow-on operations for months.
The detection lag has gotten longer, not shorter. Earlier incidents were often caught within hours because the malicious payload made noise. Modern incidents involve quiet payloads, sometimes detected only through outbound traffic anomalies weeks after the initial compromise.
What the data tells us
A cross-organization survey conducted by an industry consortium in late 2025 found that roughly forty percent of mid-sized engineering organizations still had at least one build path vulnerable to a basic dependency confusion attack. Among large organizations, the figure dropped to about twelve percent, but the absolute count of vulnerable build paths inside those organizations was still substantial because of repository sprawl.
Internal artifact repository adoption is high but not protective by default. Many organizations run an internal repository that proxies the public registry, which preserves the resolution ambiguity unless explicit scoping is configured. The mere presence of a private repo does not solve the problem.
Among confirmed 2025 and 2026 incidents, the most common root cause is not a missing private repository. It is a misconfigured project within an otherwise hardened environment, often a legacy service or a recently acquired company's codebase that did not get folded into the platform standards.
What works in 2026
The defenses that hold up in 2026 are familiar but require operational discipline.
Scoped namespaces remain the strongest single defense. When internal packages live under a scope that the organization owns on the public registry, the resolution ambiguity disappears.
Strict index resolution at the package manager level closes the residual gap. Configurations that refuse to fall back to a public index for names that match internal patterns prevent silent substitution.
Build provenance verification raises the cost of bait packages. When the build refuses to consume a dependency without a verifiable provenance attestation, attackers must compromise legitimate publishing pipelines rather than just registering a name.
Continuous discovery of internal package names in public artifacts prevents leakage from becoming exploitation. Organizations that scan their own public footprint for internal name references can pre-register or rename before an attacker does.
Acquisition integration discipline closes the long tail. Newly acquired codebases should be assumed to violate every internal standard until proven otherwise.
The acquisition integration story
Among the structural causes of persistent dependency confusion exposure in 2026, acquisition integration deserves a separate mention. A meaningful share of public incidents trace to recently acquired codebases that have not been folded into the acquirer's platform standards. The pattern is consistent: an established organization with hardened build configurations buys a smaller company, and the smaller company's projects continue to build under their original configurations for months or years afterward, often because the acquirer's platform team is overloaded with broader integration work.
Several publicly disclosed 2025 and 2026 incidents fit this pattern exactly. The malicious package landed in a build path that belonged to an acquired subsidiary, and the broader organization's hardened build configurations did not apply because the subsidiary's projects had not been migrated. The cleanup involved both the immediate incident response and an accelerated platform migration that the organization had been deferring.
The defensive implication is that acquisition integration timelines should treat build security as a Day-0 concern rather than a Day-180 concern. The cost of accelerating the platform migration is real but bounded. The cost of an incident driven by a deferred migration is unbounded and lands at the worst possible time.
How Safeguard helps
Safeguard's manifest scanning identifies dependency confusion risk patterns across npm, PyPI, RubyGems, NuGet, Maven, and container ecosystems, flagging configurations that allow public resolution to override internal names. The platform continuously crawls customer public artifacts for leaked internal package references and surfaces those references with an explicit risk score, allowing platform teams to pre-register or rename before exposure becomes exploitation. Policy gates can block deployments that include dependencies resolved from unexpected sources, and SCM integrations route alerts directly to repository owners. For organizations carrying the long tail of legacy projects and acquired codebases that still drive most modern dependency confusion incidents, this is the difference between a structural defense and a hope-it-doesn't-happen posture.