Dependency Confusion: Researcher Hacked Apple and Microsoft

Dependency Confusion: How a Researcher Hacked Apple and Microsoft

📋 Key Takeaways
  • Birsanโ€™s research began where much supply-chain research does: someone elseโ€™s disclosure.
  • The trick lives in resolver precedence. Most enterprises configure a private registry (Artifactory, Nexus, GitHub Packages) as a mirror/proxy that fronts public registries.
  • Dependency confusion remains the supply-chain attack that requires zero vulnerabilities โ€” only naming discipline, which makes it the cheapest attack to prevent and the most embarrassing to fall to.
  • Yes, wherever resolver configuration is sloppy โ€” which periodic bug-bounty reports and copycat registrations keep confirming.
9 min read · 1,614 words
Educational & Ethical Use Only — This article is provided for educational and ethical cybersecurity research purposes only. The techniques described should only be used on systems you own or have explicit permission to test. Always follow responsible disclosure and the laws applicable to you. Mitigations are included so engineers can harden real systems.
Securityยท 9 min read

In February 2021, security researcher Alex Birsan published a report that read like a magic trick: he had received bug bounties from more than 35 major companies โ€” Apple, Microsoft, PayPal among them โ€” for code that did nothing but exist. His technique, dependency confusion, exploited package-manager naming rules to get his own code auto-installed into corporate builds. Within weeks, copycats were doing it for extortion.

Passwordless in 2026: Why Passkeys Are Finally Killing the Password (and How Attackers Are Adapting)

What Studying 33 Historic Cyberattacks Taught Me About Defending Systems Today

Quick Answer
Dependency confusion abuses how package managers resolve names between public registries (npm, PyPI, RubyGems) and internal/private registries. When an internal package name โ€” say company-utils โ€” has no public counterpart, an attacker registers that name on the public registry. Build systems that check public sources “for completeness” then pull the attacker’s higher-versioned package and execute its install hooks inside the corporate network. Birsan’s February 2021 writeup demonstrated it against 35+ organizations; copycats added ransom notes to the payload. The durable fix is boring: registry namespace policy, pinning, and never letting builds reach public registries for internal names.

What happened

Birsan’s research began where much supply-chain research does: someone else’s disclosure. After the November 2020 awepono/npm-internal-packages work and discussions with other researchers, he tested a hypothesis about companies whose internal package names he could enumerate โ€” from public JS bundles, GitHub slip-ups, and LinkedIn-referenced repositories. He registered matching names on public npm/PyPI/RubyGems registries, pushed a version like 99.0.0, and added a trivial post-install script that phoned home with the hostname and path. No exploits, no data theft โ€” just proof of execution. Over weeks, callbacks arrived from build machines and developer laptops inside Apple, Microsoft, PayPal, Shopify, Netflix, Yelp, Tesla and dozens more. Each paid a bounty; his Medium post, “Dependency Confusion: How I Hacked Into Apple, Microsoft and Dozens of Other Companies,” landed on 9 February 2021 and detonated across the industry.

Within days, the technique was industrialised. In mid-February 2021, attackers targeting two fintech firms (among them reported cases at Snyk-disclosed customers) pushed packages whose install scripts not only phoned home but dropped ransom notes demanding payment to prevent “further action.” Fiji and other researchers documented hundreds of copycat registrations hunting for internal-name collisions across ecosystems. Registries responded with namespace-protection policies โ€” notably, GitHub/npm tightened rules around typosquat-adjacent registrations, and PyPI increased publisher verification options โ€” but the underlying resolver behaviour remained: it is a design property, not a bug to patch away.

The episode also crowned a recognition that SSRF-style logic flaws in build infrastructure are a top-tier risk class. It sits on the timeline between SUNBURST (six weeks earlier) and Log4Shell (ten months later) as the middle chapter of the modern supply-chain era: SUNBURST showed vendors can be compromised; dependency confusion showed the assembly itself can be attacker-controlled without touching anyone’s network.

How it worked

The trick lives in resolver precedence. Most enterprises configure a private registry (Artifactory, Nexus, GitHub Packages) as a mirror/proxy that fronts public registries. Resolution order and version selection, however, still favour the highest semver match across sources. An internal-only name never reserved publicly is therefore claimable by anyone.

company build requests package "zorg-utils" v1.2.0 (internal)
   private registry proxies: check internal - found
   ALSO checks public registries (default proxy behaviour)
        |
attacker pre-registered "zorg-utils" v99.0.0 on npm/PyPI
   semver: 99.0.0 > 1.2.0 -> public package WINS resolution
        |
post-install script executes on build/CI runner
   -> attacker code runs inside corp network
   -> exfil hostname, paths, env vars (or ransom note)

Two details make it durable knowledge. First, internal names are embarrassingly enumerable: JavaScript bundles shipped to browsers, public repos with typos, and job posts reveal them; Birsan needed no insider access for any of the 35+ hits. Second, the primitive is ecosystem-agnostic โ€” npm, PyPI, RubyGems, and (with variations) Go modules and Docker tags all had analogous behaviours, which is why “name your internal packages under a reserved scope” became universal guidance.

Impact and numbers

Metric Value Source
Organisations compromised in original research 35+ (Apple, Microsoft, PayPal, Tesla, Shopify…) Birsan Medium writeup, 2021-02-09
Bounties collected >$130,000 aggregate Birsan disclosures
Copycat extortion cases within 2 weeks (fintech-targeting packages with ransom notes) Snyk/Daniel Lessellovich reporting
Ecosystems affected npm, PyPI, RubyGems (concept generalises) writeup + follow-on research
Payload executed post-install script (hostname/path/env exfil) Birsan telemetry screenshots

Timeline

Date Event
2020-11 Related npm internal-packages research (awepono) sets the stage
2021-02-09 Birsan publishes dependency-confusion writeup; industry-wide review begins
2021-02 (mid) Copycat packages with ransom notes target fintechs
2021-02โ€“03 Registry policy tightening; enterprises audit resolver configs
2021 onward Technique joins the standing supply-chain playbook (typosquats, protestware, hijacks)

Why it still matters in 2026

Dependency confusion remains the supply-chain attack that requires zero vulnerabilities โ€” only naming discipline, which makes it the cheapest attack to prevent and the most embarrassing to fall to. Every registry-namespace policy, provenance-verification option, and SBOM initiative since 2021 traces partly to February 2021. The modern defensive stack โ€” scoped internal names, resolver allow-lists, lockfile enforcement, install-hook restrictions โ€” is now standard guidance in our software supply chain security guide, and the attack’s descendants (from protestware payloads to AI-model registry confusion) keep proving the class survives each new ecosystem.

Detection and hardening takeaways

  • Namespace your internal packages. Reserve your org scope on public registries (e.g., @company/) and use it for anything internal, even if never published.
  • Lock resolution to declared sources. Configure private registries in proxy-only mode for approved public scopes; internal names must never resolve publicly.
  • Enforce lockfiles hash-pinned in CI. Verify package-lock.json/Pipfile.lock integrity in CI; flag any resolution that differs from the lock as a supply-chain event, not a warning.
  • Restrict install hooks. Run installs with lifecycle-scripts disabled by default; allow-list the few packages that legitimately need them.
  • Alert on first-seen internal names going public. Monitor registry for your org’s internal package names appearing publicly โ€” treat as a supply-chain incident, not a curiosity.

FAQ

Is dependency confusion still possible in 2026?

Yes, wherever resolver configuration is sloppy โ€” which periodic bug-bounty reports and copycat registrations keep confirming. The mitigations are well known and cheap, which is precisely why falling to it in 2026 reads as negligence rather than misfortune.

How is this different from typosquatting?

Typosquatting waits for a human to mistype a name; dependency confusion needs no mistake โ€” the build system itself selects the attacker’s package because version arithmetic prefers it. The attacker also does not guess: internal names leak from bundles and repos, so targeting is precise.

What did the original research actually execute on victim machines?

A post-install script that collected the machine hostname, working directory, and installation path and sent them to Birsan’s collection endpoint โ€” deliberately non-invasive proof-of-execution. The copycats demonstrated what the same primitive looks like with criminal intent: identical mechanism, ransom note instead of ping.

Dependency confusion and the namespace-integrity class

The dependency-confusion technique โ€” registering public-registry package names matching a company internal package names, letting the public registry version outrank internal ones in resolution order โ€” earned its researcher a payout and the industry a permanent new checklist item. The class it defined, namespace integrity: every dependency resolver that blends public and private sources inherits a name-collision attack surface, and internal package names are frequently guessable from public artifacts (job postings, leaked code, documentation) or simply generic.

The mitigations, now standard across registries and build systems: scope-qualified internal namespaces so collisions are structurally impossible; resolution-order pinning so internal sources always win on collision; and dependency manifests audited for any package that resolves from a different source than expected โ€” the lockfile discipline extended from version-pinning to origin-pinning. Each registry (npm, PyPI, Artifactory configurations) implemented controls differently, which keeps the audit item alive: the class recurs wherever resolution logic trusts names over provenance.

The deeper lesson the researcher demonstration provided: supply-chain attack surface is not only code content but resolution logic โ€” the machinery deciding which code runs. The subsequent incidents in this series exploited content (trojanized updates), identity (maintainer takeover), and resolution (confusion), and the complete supply-chain program addresses all three: pinned provenance for content, verified transitions for identity, and namespace integrity for resolution. The technique that beat Apple and Microsoft internal systems did so with a registration form โ€” the cheapest intrusion in this entire historical record, priced accordingly in defensive attention.

The researcher disclosure itself set a template worth noting: responsible private disclosure with proof across multiple major targets, coordinated public education after fixes, and a bug-bounty payout for a technique that conventional programs had no category for. The sector response โ€” registries shipping namespace controls within weeks โ€” demonstrated that supply-chain defenses move quickly when demonstrations are irrefutable and harmless, a contrast with the incident-driven timeline most defenses require. The lesson embedded for security research: the registration-form attack earned its place in every subsequent supply-chain checklist precisely because it broke nothing while proving everything.

The registration-form attack: harmless in execution, irrefutable in proof, permanent in checklist โ€” the standard every subsequent supply-chain disclosure now measures itself against.

The namespace-integrity audit also generalizes beyond package registries to every blended-resolution environment: DNS split-horizon configurations, internal-versus-public container registries, artifact repositories fronting multiple upstreams, and even identity-federation trust decisions all resolve names against multiple authorities, and each resolution point inherits the confusion surface. The audit question โ€” can a hostile registration in one authority win resolution against another โ€” applies verbatim across all of them, and the answer at most organizations includes at least one inherited configuration nobody has examined since it was deployed. The technique earned its checklist line for registries first; the checklist line earns its audit across the whole resolution landscape.

More on this topic

Hmmnm
Published by Hmmnm

Hands-on cybersecurity tutorials, CVE breakdowns, and guided learning paths โ€” written and lab-tested by the Hmmnm team.

This article is part of the guided learning path Software Supply Chain Security โ€” track your progress there.
Need this kind of testing done for your organization? Hmmnm Supply Chain Security Assessment service โ€” fixed quote after a free scoping call.
Keep going โ€” the structured way
This post is one step. The learning paths chain the next ones for you, with progress tracking and no account needed.
Follow a learning path โ†’

Prabhu Kalyan Samal

Application Security Consultant at TCS. Certifications: CompTIA SecurityX, Burp Suite Certified Practitioner, Azure Security Engineer, Azure AI Engineer, Certified Red Team Operator, eWPTX v3, LPT, CompTIA PenTest+, Professional Cloud Security Engineer, SC-900, SC-200, PSPO I, CEH, Oracle Java SE 8, ISP, Six Sigma Green Belt, DELF, AutoCAD. Writing about ethical hacking, security tutorials, and tech education at Hmmnm.