Software supply chains are complex ecosystems where even a single vulnerability can lead to widely spread security issues. This blog focuses on supply chain account takeovers, particularly in NPM packages, and explains how attackers exploit expired email domains and leaked credentials to gain access. Through real-world research and examples, we reveal the scale of the risks involved and the potential impact on interconnected projects. You’ll find a detailed walk-through of manual and automated approaches to identify and address these vulnerabilities. We also share findings from a global worldwide scan that highlights the severity of this issue and the need for proactive measures. By the end, you will have actionable strategies to secure your dependencies and reduce the risk of account takeovers.
What is the Software Supply chain?
The software supply chain refers to everything that contributes to the code-base until it reaches production, including dependencies, binaries, libraries, and other components. It is the interconnected process of designing, developing, and distributing software, where each element plays a critical role.
The software supply chain works by integrating various components and processes involved in creating and delivering software. Developers use open-source libraries, third-party tools, and dependencies to build applications, which are then tested and deployed. Each step, from writing code to deploying it in production, involves multiple contributors and systems.
Just like in physical or traditional supply chains, vulnerabilities in one part can expand through and affect the entire system. With organizations heavily relying on external sources, securing these supply chains has become more important than ever. Protecting every link in the chain ensures the quality and security of the software and its end-users.
What is NPMjs
NPMjs is a popular package manager, making it easy to manage JavaScript libraries and dependencies. It provides a huge collection of open-source packages that developers can use to build and enhance their projects. With NPM, you can quickly install, update, and manage dependencies without much hassle. It also helps keep track of different versions to avoid compatibility issues. The simple command-line tool lets you run scripts, publish your own packages, and handle project setups smoothly. NPM has become an essential tool for modern JavaScript development, saving time and effort for developers.
NpmJS Package
NPM packages, and most libraries in general, often rely on other packages to function, creating a chain of dependencies. This means that a package depends on another, which in turn depends on yet another, forming an interconnected web. If one dependency encounters an issue, it can impact many others down the chain, causing widespread problems. Understanding key terms is crucial when navigating this ecosystem:
- Package: A collection of code, modules, or tools designed to perform specific tasks.
- Maintainer: The person or team responsible for managing and updating a package.
- Dependants: Other packages or projects that rely on a specific package.
Below, you will find a sample express package and its related stats, demonstrating how interconnected this web of dependencies can be.
Problem Statement
As we now understand, NPMjs is a registry where maintainers manage packages linked to their accounts, which are further associated with an email address. These accounts are critical for publishing, updating, and maintaining packages used across various projects. But what happens if a maintainer’s account is compromised?
There are two common scenarios to consider:
- Email Takeover: If the email address associated with the account is vulnerable to takeover, attackers could gain control over the account.
- Leaked Credentials: If the maintainer’s password has been exposed in a data breach and not updated, it could be used to access the account.
Both situations pose significant risks, as attackers could manipulate packages, injecting malicious code that could affect all dependent projects.
NPM packages are managed by maintainers who can update and modify them, with their accounts tied to email addresses. If the domain of an email address expires (e.g., [email protected]), an attacker could buy the domain, recreate the email, and gain access to the maintainer’s account. This allows attackers to push malicious updates, impacting countless projects dependent on the package.
In 2022, a security expert demonstrated this risk by taking over the email domain of an NPM library with six million weekly downloads to highlight the issue. Read more: “Email domain for NPM lib with 6m downloads a week grabbed by expert to make a point”.
At the time, no public method existed to test for this vulnerability, leaving organizations exposed. To address this gap, our director proposed a simple manual approach, which was featured in a blog on The Register: “NPM dependencies vulnerable”. This solution provided an accessible way for everyone to identify potential risks in their supply chain.
The manual approach involved these steps:
- List all the packages your company uses or refer to pre-organized lists in your codebase.
- For each package, retrieve maintainer email addresses using this NPM CLI command:
npm view packagename maintainers.email - Copy the output containing email addresses.
- Extract and separate the email addresses to create a list of domains.
- Run a Whois lookup on all the domains to check for expired ones.
- Use third-party tools like bulk email identifiers or validators for further validation.
While this method helped solve the problem at that time, it was not efficient or scalable for organizations managing a large number of dependencies.
Automated Approach
For organizations, managing hundreds of packages makes it impractical to rely on manual methods. It is also preferable to repeat the process regularly to ensure ongoing security. To address this challenge, we created an automated approach that can even be integrated into a cron job, helping organizations continuously safeguard their codebase against this attack vector.
These motivations led us to share a script at conferences and open-source it for everyone to use. You can find it here: npm-account-hijacking-scanner.
To use the script:
- Test a single package with this command:
bash npm-account-hijacking.sh -p package_name_here
- Scan a whole list of your packages by compiling them into a file, e.g., packages.txt, and running:
bash npm-account-hijacking.sh -f packages.txt
- This automated solution simplifies the process and scales effortlessly, ensuring your supply chain remains secure.
World Wide Scan at scale for this vulnerability
Laburity is not just a cybersecurity services company, it is deeply into hardcore research as well. With a commitment to create awareness, we decided to explore the extent of this vulnerability by scanning all available NPM packages at the time.
The goal of this research was to evaluate the general security posture of these packages, specifically against account takeover possibilities.
For this World-Wide Scan, packages were collected from publicly available sources. With customized and optimized scripts, along with high-RAM servers and dedicated resources, we conducted a comprehensive analysis to shed light on the risks and vulnerabilities within the ecosystem.
Operation Methodology
Phase 1: Collecting All Packages
The first step was to collect every available npm package on the internet. At the time, npm’s repository held around 2.1 million packages (2,118,539 to be precise), accessible via npmjs.com. This was a massive dataset, but we successfully gathered the packages with the right setup, giving us a complete starting point for our research.
Phase 2: Gathering Emails Linked to Packages
Once we had a complete collection of npm packages, we moved to Phase 2, where we focused on collecting email addresses linked to each package. These emails are of the package maintainers or contributors and can help trace package ownership or responsibility. Gathering this information was crucial, as we would later use these emails to evaluate expired domains and potential security risks associated with the packages.
This phase was particularly challenging, as we needed to extract email addresses from each npm package’s metadata across millions of packages. To handle this, we deployed 10 cloud instances, each equipped to fetch, process, and store emails from the packages in a centralized storage system. This allowed us to manage the vast volume of data without compromising on speed or organization. The result was a unified database containing emails linked to every npm package we scanned, ready for further analysis.
In our research setup, we utilized up to 10 cloud instances, each equipped with 16GB of RAM, which provided the performance needed to efficiently handle the extensive scanning processes required. This infrastructure was well-suited to support high-volume data extraction, sorting, and domain analysis across millions of npm packages. With this configuration, we could run complex operations in parallel, ensuring speed and reliability without compromising the thoroughness of our research. The robust setup allowed us to quickly gather, process, and analyze data at a large scale, giving us valuable insights into potential vulnerabilities within the npm ecosystem.
Phase 3: Sorting and Filtering Unique Emails
After gathering all the emails, we conducted a detailed sorting step. A total of 6,789,211 (6.7+ million) email addresses were extracted from npm packages, including duplicates. By carefully filtering these, we narrowed down the list to 603,887 unique email addresses. This step ensured that we had a refined set of unique contacts, which would be essential in our next phase for domain expiration analysis.
Phase 4: Identifying Expired Domains
In this step, we set out to check the status of 132,632 domains (from 6,789,211 email addresses) associated with the unique email addresses gathered earlier. Using a WHOIS lookup, we verified each domain’s expiration status. Since WHOIS lookups have strict rate limits, we had to set up a parallel processing system and integrate APIs to work around the limitations. Domains that have renewal dates have been passed and could be purchased from the online providers were marked as expired domains. By the end, we identified 675 expired domains, providing us with clear insights about the domains that can be taken over by malicious users.
Phase 5: Reverse Analysis and Vulnerable Package Identification
For our final phase, we conducted a reverse analysis to pinpoint vulnerable packages. Here, we cross-referenced email addresses tied to expired domains with our raw list of emails gathered in Phase 2. This comparison helped us identify packages that might be vulnerable to NpmJS package takeover vulnerability. We found that 2,843 npm packages were linked to expired domains, marking them as vulnerable to potential takeover or exploitation.
Significance
Our research revealed that 2,843 packages were directly vulnerable to account takeover. While this may not seem alarming at first glance, the interconnected nature of the software supply chain magnifies the risk. Remember the web of dependencies? Packages often depend on other packages, and a single compromised dependency can put countless projects at risk.
For instance, even if your organization uses Package X, but Package X depends on a vulnerable Package Y, your entire system could be compromised due to Package Y.
To illustrate the significance, consider these figures related to the vulnerable 2,843 packages:
- Forks: These packages were forked more than 413,000 times, spreading potential vulnerabilities across countless projects.
Significance: Compromised forks can propagate malicious code widely.
- Dependent Repositories: Over 257,000 repositories directly depended on these packages.
Significance: A vulnerability in one package could affect thousands of repositories, putting organizations at risk.
- Dependent Packages: 93,000 packages relied on these vulnerable ones.
Significance: The cascading impact can affect entire ecosystems that use these packages.
- Contributors: More than 50,000 contributors were involved in projects tied to these packages.
Significance: Such a large contributor base means widespread adoption, amplifying the potential impact of any vulnerability.
This analysis highlights the critical need for proactive measures to secure not just the packages you use but also their dependencies, as even one vulnerability can ripple across the entire supply chain.
How to Protect Against Account Takeover and Supply Chain Attacks
To protect against account takeover and other supply chain threats, adopting a dynamic approach is essential.
- Implement Multi-Factor Authentication everywhere to add an extra layer of protection.
- Scan your SDLC with tools like the one we shared, combined with others, to identify vulnerable packages.
- Avoid blindly trusting any code available on the internet and always validate its integrity.
- Use automation to ensure dependencies are regularly updated.
- Adopt Zero Trust Architecture principles to minimize trust and reduce attack surfaces.
- Validate checksums to verify the integrity of downloaded packages.
- Evaluate the security postures of third-party vendors and dependencies.
- Perform and store regular third-party risk assessments.
- Make regular code reviews a standard part of your process.
- Include penetration testing in your development lifecycle to identify vulnerabilities.
- Keep on top of security bulletins and advisories.
- Implement SBOM to maintain a detailed list of software components, versions, and metadata.SBOM provides visibility into your software’s supply chain and helps manage risks effectively.
Tools to scan your dependency tree for security risks
- GitHub Security Alerts
- Dependabot
- GitLab Security Scanning
- npm audit
- retire.js for Node.js
- bundler-audit for Ruby
- OWASP Dependency-Check for Java and .NET
- ShiftLeft and bundler-integrity for enhanced scanning
Global Recognition for Our Research
Our global research on NPM package vulnerabilities and account takeover risks has been presented at prominent platforms, conferences, and events globally, proving its importance and impact:
- Featured on The Register: NPM dependencies vulnerable
- Presented at Black Hat MEA 2022, Riyadh, Saudi Arabia: Event Details
- Presented at ThreatCON 2023, Kathmandu, Nepal: Agenda
- Presented at EOCON 2023: Eyes Open Security
- Presented at AllDayDevOps 2023: Event Details
- Presented at Conf42 DevSecOps 2023: Event Details
- Presented at DeveloperWeek 2024: Event Details
- Presented at DevSecCon: Session Video
- Presented at Security Analyst Summit 2023, Thailand: Session Video
Conclusion
Supply chain account takeovers present a significant risk in today’s software development processes. This blog has outlined practical steps, from manual checks to automated solutions, that can help organizations stay ahead of potential threats. By securing dependencies and adopting best practices, you can protect not just your codebase but the broader ecosystem it impacts. Security in the supply chain is about maintaining trust and ensuring resilience. Taking proactive steps today can save you from consequences tomorrow.
How can we help?
Finally, consider professional services from experts like Laburity. We specialize in static code analysis, supply chain security audits, and uncovering vulnerabilities beyond account takeover, addressing hundreds of potential weaknesses for comprehensive security. You could schedule a call with us at https://calendly.com/laburity/meeting or reach out at [email protected]
Authors and Researchers
Hassan Khan Yusufzai:
Director @ Laburity
Hassan Khan Yusufzai is a security researcher specializing in penetration testing, supply chain attacks, and code security. A certified OSCP and top-ranked bug bounty hunter, he has presented at Black Hat MEA and ThreatCon, contributed multiple CVEs, and developed tools like GemScanner. His work has earned recognition in over 200 Hall of Fames, including Google and Microsoft.
Linkedin: https://www.linkedin.com/in/hassankhanyusufzai/
Danish Tariq:
Director @ Laburity
Danish Tariq is a cybersecurity expert with over 10 years of experience in penetration testing, vulnerability assessments, and supply chain security. A speaker at Black Hat MEA, ThreatCon, and HITB, he is recognized by tech giants like Microsoft and Apple for his impactful security research.