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
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:
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:
To manage tokens using the npm command-line client, follow these steps:
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
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!
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.
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.