How Hackers Exploit Dependency Confusion to Hijack Packages and Earn Bounties

Security researcher Alex Birsan demonstrates how simple dependency‑confusion attacks—registering private package names on public registries like npm, PyPI, and RubyGems—can silently compromise internal build systems of major tech firms, yielding high‑value bug bounties while exposing systemic risks in package management.

21CTO
21CTO
21CTO
How Hackers Exploit Dependency Confusion to Hijack Packages and Earn Bounties

Hackers often seem like mystics, but many network attacks rely on simple, effective methods.

Alex Birsan recently discovered over 30 vulnerabilities in tech companies using a straightforward technique, earning substantial bug bounties.

He described his approach in a personal blog, which we summarize below.

Since learning programming, I have been puzzled by the simple command: pip install package_name Languages like Python use this official method to install dependencies from public repositories, which anyone can upload packages to.

When installing packages from external sources, we trust the publisher to run code on our machines, a trust that can be abused by malicious actors.

Indeed, any package hosting service cannot guarantee that uploaded code is free of malware. Research shows that domain‑typosquatting attacks are highly effective for gaining access to random PCs.

Other known dependency‑attack vectors include tampering with existing packages or uploading malicious code under abandoned package names.

Idea

In summer 2020, while attempting to compromise PayPal, Justin Gardner shared interesting Node.js source code found on GitHub.

The code, intended for internal PayPal use, mixed public npm packages with private ones that did not exist on the public npm registry.

This raised several questions:

What if malicious code is uploaded to npm under these names? Could internal PayPal projects start using the new public packages instead of private ones?

Would developers or automated systems begin running these packages?

Could this method be used to earn bug bounties from tech firms?

Would the attack work against other companies?

I set out to answer these questions.

The plan was to upload my own “malicious” Node package under all unclaimed names on npm, causing each installation to “call home.” If any package were installed on a PayPal server, the code would immediately notify me.

All targeted organizations had authorized testing through public bug‑bounty programs or private agreements; unauthorized testing is prohibited.

“Always DNS”

npm allows arbitrary code execution during package installation, enabling me to create a Node package that collects basic information (username, hostname, install path) from each machine via its preinstall script.

To balance identification with privacy, I limited data to username, hostname, current path, and external IP.

To exfiltrate this data, I used DNS queries, which are rarely blocked or detected on outbound traffic.

The data is hex‑encoded and sent as part of a DNS query to my custom name server, which logs each query, effectively recording every machine that downloaded the package.

More is Better

I ported the attack to Python and Ruby to upload similar packages to PyPI and RubyGems.

Finding private package names involved scanning GitHub, internal package registries, and JavaScript files where package.json often leaks internal names.

Using automated scanning, I identified hundreds of undisclosed JavaScript package names belonging to target companies.

These names were then used to upload malicious packages, awaiting callbacks.

Results

The success rate was astonishing. By exploiting a single developer mistake, misconfigured build servers, or vulnerable pipelines, attackers could hijack internal packages across many large tech firms.

To date, I have observed this “dependency confusion” vulnerability in over 35 organizations across three programming languages.

Notable payouts include $30,000 from Shopify, Apple, and others; other affected companies include Netflix, Yelp, and Uber.

Implementing a backdoor in a production service requires a more complex event sequence; it is a very specific term with additional implications.

Most bug‑bounty rewards were at the maximum allowed amount, underscoring the severity of dependency‑confusion bugs.

“It’s Not a Bug, It’s a Feature”

Root causes vary: Python’s --extra-index-url can be abused to hijack dependencies; similar issues exist in Ruby’s gem install --source. Changing to --index-url mitigates some cases, but other variants remain.

Microsoft’s Azure Artifacts also exhibited similar vulnerabilities, leading to a $40,000 reward after a successful attack on Office 365.

Future Research?

Although many large tech companies have patched these issues, there remain many undiscovered internal package names and additional attack surfaces in other languages and repositories.

I encourage researchers of all experience levels to explore dependency‑management security further.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Supply ChainnpmBug Bountydependency confusionpackage security
21CTO
Written by

21CTO

21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.