Blogs
Published on
January 19, 2023

10 npm Security Best Practices to Secure your Applications

5
min read

npm stands for Node Package Manager and is one of the most powerful additions to web application programming. It allows using and sharing of reusable pieces of code in the developer community.

Today, over a million packages are available in the public npm registry, and modern applications are full of open-source components. While it looks all good from the outside, using open-source components has consequences if a proper process is not followed.

Open-source components have several vulnerabilities because of the dependencies, and if the vulnerabilities are not taken care of, hackers can easily take advantage.

Open-source security auditing is a vital part of any application security strategy, and npm package security should be a top priority in the process.

Want to know more about npm security?

This article will uncover ten npm best practices to help secure your application.

10 npm Security Best Practices

When someone uses your application, they put trust in you that your application won’t compromise their data. To make your application ready for online threats, you’ll need to follow some best practices. Here are some of the best practices to foolproof your application security.

Audit the Code for Vulnerabilities in Open-Source Dependencies

The npm repository is the largest repository of application libraries in the entire language ecosystem. The registry and the libraries are crucial for JavaScript developers as there are many pre-built components available there. This, in turn, increases the chances of open-source vulnerabilities in their application.

Plenty of npm packages have vulnerabilities and carry a significant risk if proper security auditing of dependencies is not done. Some examples of such packages include request, mongoose, superagents, etc.

Security doesn't just involve scanning for vulnerabilities when installing a package. It should also be integrated into developer workflows and monitored throughout the software development lifecycle.

This includes monitoring snapshots of your project's manifests to receive alerts when new vulnerabilities are discovered that may impact your code. By adopting this approach, you can ensure that security is considered at every stage of development, from initial coding to deployment.

Refrain from Publishing Secrets to the npm Registry

API keys, passwords, and other secrets can easily be exposed if not handled properly. These secrets may be stored in files such as a .env, which should be included in a .gitignore to prevent committing them to source control.

However, when publishing an npm package from the project's directory, there is a risk of these secrets being included in the published package on the public npm registry. It is important to take steps to prevent this from happening, such as carefully reviewing the files being published and excluding any sensitive information.

The npm CLI creates a tar archive (tarball) to publish a project to the registry. The .gitignore and .npmignore files are used as ignore patterns to determine which files and directories are added to the tarball. If both ignore files exist, everything not specified in .npmignore will be published to the registry.

This can cause problems if developers update the .gitignore file but forget to update .npmignore, potentially leading to sensitive files being included in the package.

To avoid this issue, developers can use the files property in package.json as a whitelist to specify the exact files that should be included in the package. The files property takes precedence over the ignore file. Additionally, using the --dry-run command-line argument allows developers to review how the tarball is created without publishing it to the registry.

Keep your npm Packages Updated

Most npm packages receive updates on a regular basis. Some updates are categorized as minor releases, while others are classified as patch releases. Patch releases are particularly crucial, as they address known vulnerabilities that have been reported, and their exploitation details are publicly available.

So it’s always a good idea to keep your packages updated so that there is no vulnerabilities in your application.

Use npm Audit

The npm audit command allows you to scan your dependencies for security vulnerabilities. It will scan direct, devDependencies, bundled, and optional dependencies and send them to your default repository to check for known vulnerabilities.

Running npm audit every time you run npm install is recommended. It is also a good idea to run it during important moments in your CI (continuous integration) cycle to prevent vulnerable dependencies from being introduced.

The npm audit command has several options that can help you gather information about vulnerabilities and how to fix them. Some useful options include

  • --json: This option will print the audit report in JSON format, which can be easier to parse and analyze.
  • --fix: This option will automatically fix any vulnerabilities that can be fixed by updating dependencies to newer versions.
  • --prod: This option will only audit production dependencies, not devDependencies. This can be useful if you focus on the dependencies used in your final deployed application.
  • Overall, the npm audit command is a valuable tool for ensuring the security of your dependencies and protecting your applications from potential vulnerabilities.

    Ignore Run-Scripts

    The npm CLI tool allows users to run scripts from packages. If you have ever used npm start or npm test, you have also used package run-scripts. These scripts can be declared by a package and allow the package to run certain commands during installation in a project. For example, some of these scripts may be postinstall scripts that are executed to perform housekeeping tasks.

    However, this capability can also be exploited by bad actors who create or alter packages to perform malicious actions when their package is installed. This has happened in incidents like the In recent incidents, malicious actors have exploited vulnerabilities in the npm registry by using tactics such as typosquatting and harvesting npm tokens. This has been seen in the eslint-scope and crossenv incidents, among others. A total of 37 packages have been identified as using these tactics to carry out attacks on the npm registry.

    To minimize the risk of a malicious module attack, it is important to follow these npm security best practices:

  • Always carefully evaluate and perform due diligence on third-party modules before installing them to confirm their health and credibility.
  • Wait to upgrade to new package versions; give them time to circulate before trying them out.
  • Before you start to upgrade, check the changelog and release notes for the upgraded version.
  • While installing packages, add the --ignore-scripts suffix. This will disable the execution of any third-party scripts.
  • Also, add ignore-scripts to your .npmrc project file or to the global npm configuration.
  • Use npm Author Tokens

    Whenever you log in with your npm CLI, a token is generated that authenticates you to the npm registry. This authentication prevents unauthorized access to your private modules and other sensitive information on the npm registry.

    It is also important to regularly review and revoke any unnecessary or unused tokens to maintain the security of your npm account.

    To manage tokens through the npm registry website, follow these steps:

  • Go to https://www.npmjs.com/ and log in with your npm account.
  • Click on your profile picture in the top right corner, and select "Accesss Tokens" from the dropdown menu.
  • This will bring you to the Tokens page, where you can see a list of all the tokens associated with your account.
  • Click on the "Generate New Token" button to create a new token. This will open a pop-up window where you can enter the token name and select the desired permissions.
  • Once you have created the token, you can see it in the list of tokens on the Tokens page.
  • To edit or delete a token, click on the corresponding actions in the "Actions" column for the relevant token.
  • To manage tokens using the npm command-line client, follow these steps:

  • Open a terminal or command prompt and navigate to the directory where you want to manage your tokens.
  • Run the command npm login to log in to your npm account.
  • To create a new token, run the command npm token create --read-only or npm token create --read-write depending on the desired permissions.
  • To list all the tokens associated with your account, run the command npm token list.
  • To delete a token, run the command npm token delete .
  • Note that the npm command-line client only allows you to create and delete tokens and not edit their permissions. To do that, you need to use the npm registry website as described above.

    Enable 2FA

    Two-factor authentication (2FA) is a security measure that requires users to provide two different authentication factors to access their accounts. In the context of npm security, 2FA would require users to provide both their username and password and a unique code that is generated and sent to their mobile phone or email address.

    This added layer of security helps to protect users' accounts from unauthorized access and ensures that only authorized users can access and make changes to their npm packages.

    Here are the reasons why you should enable 2FA for your npm security

  • Improved protection against unauthorized access to npm accounts and packages.
  • Added layer of security for sensitive information and confidential data stored in npm.
  • Reduced risk of data breaches and cyber-attacks.
  • Enhanced accountability and traceability of user actions on npm
  • Increased trust and credibility in the npm ecosystem for developers and users.
  • Enhanced overall security and reliability of the npm platform.
  • The command-line code for enabling 2FA is

    npm profile enable-2fa auth-and-writes

    Shift the Security Responsibilities

    When adding new packages to a project, it is crucial to make intentional changes, even if you are using a private registry. The more packages you use, the greater the potential for security vulnerabilities. As your dependency list grows, it becomes increasingly difficult to keep all those packages up to date and secure.

    It is not the responsibility of one individual to make decisions about dependencies. Instead, the whole team should take on this responsibility and work together to determine the best approach.

    Don’t Run Scripts by Default

    This attribute tells npm to skip the execution of any scripts defined in the package.json file, reducing the risk of potentially harmful or malicious code being run on your system.

    It is always best to carefully review the scripts before installing a package, but in a pinch, the --ignore-scripts attribute can provide an added layer of security. As with any potential security risk, it is important to stay vigilant and always be aware of what is installed on your system.

    npm install PACKAGE@VERSION --ignore-scripts

    Enforce the Lockfire

    Lockfire is a security feature in npm that allows you to specify version constraints for the packages your project depends on. This means you can specify a minimum or maximum version number for each package, or a specific version that your project requires. This can help prevent vulnerabilities in your project by ensuring that only tested and approved versions of packages are used.

    To enforce lockfire security in npm, you can use the npm ci command, which stands for "npm clean install". This command installs the exact versions of the dependencies specified in your project's lockfire, rather than using the latest versions available from the npm registry. This can help prevent security vulnerabilities by ensuring that your project only uses versions of packages that have been tested and approved for use.

    To use the npm ci command, first, ensure that your project has a lockfire (usually called package-lock.json or npm-shrinkwrap.json) that specifies the exact versions of all the dependencies your project uses. Then, run the following command in your project's root directory:

    npm ci

    These were the top 10 npm security best practices, but the list doesn’t end here. As a developer, the best practice to ensure npm security is to take a few steps to help improve your application's security from the beginning of the development process. Let’s discuss those steps.

    Steps Developers Should Take To Use npm Securely

    The above-mentioned practices can definitely help secure your application. However, if the developers take a few steps from the beginning itself, it will double secure the application. Here are the steps any developer should take while using npm packages.

    Always Know Which npm Packages You’re Using

    As the popularity of Node.js development grows, so do the size and complexity of its applications. The Linux philosophy of Node.js emphasizes the importance of having small, focused programs that do one thing well.

    However, as the demands on Node.js applications increase, more and more dependencies are needed to complete their tasks. This can make it difficult to maintain npm security.

    To ensure the security of your npm packages, it's important to have a comprehensive inventory of all packages you use, along with their versions and reasons for use. You should also avoid adding new packages without careful consideration and verification that the functionality cannot be achieved with a module you already have.

    By following these guidelines, you can maintain the security of your npm packages and keep your Node.js applications running smoothly.

    Keep the Packages Updated

    This also comes under the best practices; however, as a developer, it’s your responsibility to keep the packages updated from the beginning. This will help you fix all the minor issues fixed from the source itself in the latest update.

    Use Private npm Repository

    To ensure the highest level of security for your npm modules, it is recommended to set up a private npm repository inside your firewall instead of relying on a public repository. Public repositories are convenient for developers to access, but they come with the risk of security vulnerabilities.

    For example, many maintainers have poor password security, making it easy for attackers to take over accounts and add malicious code. Additionally, hackers can use social engineering tactics, such as offering to take over a project to gain access to sensitive information.

    To protect your npm modules, consider using tools to build and manage your private repository. This will allow you to vet modules for security and usability before adding them to the repo. You can also create custom modules for your developers and add them to the repository. Once your private repo is set up, monitor it continuously and provide a system for developers to request new packages. Regularly check for updates and vulnerabilities using npm audit or other tools. By implementing these steps, you can ensure the security of your npm modules.

    Scantist can Help you!

    Scantist

    Further, it also checks for all license and compliance issues related to your open-source components.

    With Scantist, you don’t need to worry about using open-source. Just focus on developing your application, and the rest will be managed by Scantist.

    try it for FREE

    Related Blogs

    Find out how we’ve helped organisations like you

    An Empirical Study of Malicious Code In PyPI Ecosystem

    How can we better identify and neutralize malicious packages in the PyPI ecosystem to safeguard our open-source software?

    The RoguePuppet Lesson: Why Software Supply Chain Security Is Non-Negotiable

    A critical software supply chain vulnerability was recently averted when security researcher Adnan Khan uncovered a severe flaw in the GitHub repository Puppet Forge in early July 2024. Dubbed RoguePuppet, this vulnerability would have allowed any GitHub user to push official modules to the repository of Puppet, a widely-used open-source configuration management tool.

    Driving Security: The Critical Role of Binary Analysis in Automotive Cybersecurity

    In the rapidly evolving automotive industry, cybersecurity has become a paramount concern. With the increasing connectivity and complexity of modern vehicles, manufacturers face unprecedented challenges in ensuring the safety and security of their products. The introduction of regulations like UN R155 and R156 has further emphasized the need for robust cybersecurity measures throughout the vehicle lifecycle.