Skip to main content

DevSecOps tools for open source projects in JavaScript and Node.js

Written by:

November 24, 2020

0 mins read

In this article, I’d like to propose best practices and discuss how maintainers, and developers, can adopt DevSecOps tools for open source projects to better improve their security posture.

We are not short on security incidents and horror stories about malicious packages in the JavaScript open source ecosystem. As citizens of the open source ecosystem, whether we are maintainers or consumers of projects, we should attribute proper attention to open source security to ensure we’re not all put in harm’s way.

The following curation of DevSecOps tools and security practices is based on my experience at Snyk of working closely with the verdaccio npm lightweight private proxy and registry project. Specifically, we are going to cover the following:

  1. Adopt a responsible security disclosure policy and include it in your projects as part of your security guidelines.

  2. Establish a security process and security guidelines.

  3. Ensure all maintainers and collaborators have two-factor authentication (2FA) enabled for both GitHub and the npm registry.

  4. Avoid a data breach and sensitive information exposure by using git pre-commit hooks to prevent developers from leaking passwords and secrets when they commit and push to a repository.

  5. Integrate open source dependency scanning and fixing to prevent security vulnerabilities in 3rd party open source packages. Integrating Snyk into the git workflow could help you.

  6. Use the Snyk Advisor to search and compare over 1 million open source packages on the npm registry, and choose the right npm package.

Adopt a responsible security disclosure policy

A responsible security disclosure policy allows security researchers and other users to report a security vulnerability affecting the project and to manage the process in a private discussion that is hidden from prying eyes.

The private discussion then allows for a more in-depth investigation of all involved parties—namely the maintainer and the security researcher, as well as triaging of the vulnerability, a proof-of-concept, and finally a fix to remediate the vulnerability.

Once a fix is available and has been released for a reasonable amount of time, the vulnerability can be disclosed publicly and users will be able to upgrade in order to receive the security fix.

This process helps protect users from security vulnerabilities that would be disclosed with no prior coordination of the project.

For a more elaborate explanation on why responsible security disclosures are so important, check out Understanding Responsible Disclosures. The Snyk Security Research Team provides a program for open source project maintainers, where our team collaborates on triaging the vulnerability, working on a fix, and requesting a CVE. This is available for many language-based ecosystems, such as Node.js, Java, .NET, Python, Ruby, PHP, and others:/.

Establish security guidelines

A project should have security processes in place to accommodate for incident response among its team members and communicate its security readiness and policies for security researchers.

The following information should be available:

  1. Security policies for the project, for example, which vulnerabilities are considered security issues and which do not constitute a vulnerability.

  2. A responsible security disclosure policy or references to existing programs that accommodate this.

  3. Contact information for reaching out to the project’s security leads. It is advised to adopt the relevant fields from the security.txt spec.

  4. Avoid leaking secrets—whether you’re making use of API keys, passwords, or other secrets, they can very easily end up leaked into source control or even a published package on the public npm registry.

To allow for effective communication of the above, this information is advised to be provided in a SECURITY.md file at the project’s top-level directory.

All project collaborators should enable 2FA

As maintainers and collaborators who are trusted to release versions of your project that are safe from malware, we should ensure that our accounts don’t get compromised. This had already happened before on npm with the eslint-scope security incident, the mailparser npm package, and others.

Yes, compromising packages and injecting malware has happened before and will happen in the future. You can read more on what is a backdoor and see how easy it is to build one with Node.js and publish it to npm.

To minimize an account takeover and package compromise incident, ensure the following:

  1. All collaborators enable two-factor authentication (or other forms of multi-factor authentication) to the source code repository.

  2. All collaborators who have publish access for the package enabled two-factor authentication to the npm registry.

  3. Don’t forget to test your projects for known backdoors!

Avoid data breaches and sensitive information exposure

A common issue with managing public repositories for open source projects is that it is far too easy to mistakenly publish secrets such as passwords and API keys, or other sensitive information.

I’ve seen this happening multiple times, both for open source projects as well as inner-source private projects—which aren’t immune to the impact of secrets leaking. Remember—git remembers all!

Using git hooks

You may have secrets in your working directory in designated files such as a .env file that are meant to be ignored from being committed to an SCM or package registry, yet mistakes are bound to happen which is why we need controls in place to make sure prepare against this possibility.

There are a bunch of great tools available, that can statically analyze your commits, via a pre-commit Git Hook to ensure you’re not trying to push any passwords or sensitive information into your GitHub repository. Commits will be rejected if the tool matches any configured regular expression patterns that are designed to find sensitive information. It may slow down pushes a tiny bit, but it’s well worth it.

You can also use such tools in your CI and CD pipelines, for example,  GitGuardian, to actively break builds when sensitive information is found in code or a config file. Having team-wide rules that prevent this from happening is a great way to police bad actions in the existing developer workflow.

Why is this important?

  1. https://github.blog/2019-05-14-git-ransom-campaign-incident-report/

  2. https://about.gitlab.com/2019/05/14/git-ransom-campaign-incident-report-atlassian-bitbucket-github-gitlab/

Preventing password leaking: the detect-secrets tool

It is a high-security concern to ensure that passwords and sensitive information aren’t leaked by the maintainers and developer of the Verdaccio npm open source project, used for providing an npm private registry and proxy server.

I joined them in order to collaborate on a Pull Request that adds a tool to their development workflow, guarding them, from preventing the leaking of sensitive information to source control.

wordpress-sync/image1-21

The choice for Yelp’s detect-secrets project is due to its flexibility in managing a manifest for secrets in a repository and overall architecture of auditing detected secrets, allowing for offline secret manifests management for tracking and whitelisting, with preventative measures employed on user interaction with the git repository.

Modes of Operation:

  1. Preventative measure: to protect users from introducing secrets into source code control, the project provides a detect-secrets-hook executable that receives files as arguments and tests them for secrets. Upon detecting any secrets, it alerts and aborts the process altogether.

  2. Offline scan for audit and whitelisting: the aforementioned preventative measure is applied only when commits are made, and so it will only prevent secrets from being added to the point it is introduced. An offline allows scanning all files in a git repository to create a baseline of known secrets that can be audited for whether they pose a false positive or a secret that needs to be removed, and revoked properly.

The two modes of operations are complementary and allow the flexibility of adopting either of them independently as it fits developers.

Using detect-secrets as a tool in your git hooks may not be well suited for all projects, especially JavaScript and Node.js because the tool requires a functional Python environment. If this doesn’t cause any issues for your project, you can install it and start using it as follows:

$ pip install --user detect-secrets

Alternatively, here’s a recipe on how to use it for npm-based JavaScript and Node.js projects and prevent sensitive information exposure with detect-secrets.

In order to provide a preventive pre-commit measure for JavaScript developers, we will build on the following two project dependencies:

  • husky enables npm projects to easily manage git hooks for developers through the use of a project-level manifest and an npm dependency that streamlines hooks management for JavaScript developers with the tools they are familiar with.

  • lint-staged enables executing tasks such as linters and formatters on staged files, so they can be updated with pre-configured compliance when committed to source control.

Note: lint-stagedis optional, but is usually a rather common dependency for JavaScript projects.

Once both lint-staged and husky are added as project development dependencies, the project’s package.json can be updated with the required configuration for the pre-commit hook:

"husky": {
   "hooks": {
     "pre-commit": "lint-staged"
   }
 },
 "lint-staged": {
   "linters": {
     "**/*.js": [
       "detect-secrets-hook --baseline .secrets-baseline"
     ]
   }
 }

At this point, if a file is being added or updated in git’s source control, it will be tested for sensitive information such as secrets, passwords, and API keys, and the repository commit operation will halt.

Note: monorepos that have husky and lint-staged dependencies installed inside nested directories and not at the top level, .git/ directory will require an update to the lint-staged configuration to accommodate for that case:

 "lint-staged": {
   "relative": true,
   "linters": {
     "**/*.js": [
       "detect-secrets-hook --baseline .secrets-baseline"
     ]
   }
 }

Baseline for secrets

To ensure that all files in the git repository have been tested for possible secrets, we issue an ad hoc scan:

detect-secrets scan > .secrets-baseline

Once scanned, the generated output makes use for a baseline of whitelisted secrets across the code-base. The JSON results include metadata of all plugins used, when this scan was generated, a hash of the secret, and file details for which the secret was found.

Sometimes, secrets-like strings may appear in documentation like README files, and so they are expected to be committed and be kept in source control as they aren’t real secrets. Other times, secrets are indeed found and need to be handled in a secure manner. After being handled, a new scan action will result in a new baseline without the secrets that were removed.

To help teams remediate secrets found in their code base, the tool offers an audit capability which will iterate through the baseline file and interactively prompt the user to toggle whether a secret is false-positive—such as a secret used in test files—or a true positive, in which case it already exists in source control and needs to get removed.

Integrating Snyk to develop fast and stay secure

How do you develop fast and stay secure?

Maintainers and collaborators of open source projects often end up including open source packages in their projects. Further yet, they keep on adding more dependencies in time. How do you know the next dependency you add is not vulnerable?

The Verdaccio team created a git integration that integrates Snyk into their GitHub repository, for a fully supported git workflow that provides security tests in the CLI.

wordpress-sync/image3-15

Want to get started quickly with Snyk? Check out this guide to get from zero to security hero. Better yet, you can watch a 1:35-minutes video to swiftly get started with Snyk:

Use the Snyk Advisor to choose the right package

The Verdaccio npm project makes use of dependencies like commander, but as a developer, how do you know if the npm package commander is a healthy project?

Luckily, the Snyk Advisor helps you search and compare over 1 million open source packages and quantify key decision factors like the project’s maintenance, popularity, community, and security posture. With that information, the Snyk Advisor proposes a metric for an overall package health score.

wordpress-sync/image2-24

Verdaccio also depends on cookies and cors. How do they score? I’ll let you find out yourself!

Closing words

To summarize, we reviewed several DevSecOps tools and security practices that you can use as a maintainer of an open source project, or as a developer working on an open source project. From preventing passwords leaking to source control, to testing and monitoring your dependencies for vulnerabilities, and up to choosing the right npm package using the Snyk Advisor.

I recommend you to follow-up on this read with:

How to Build a Security Champions Program

Snyk interviewed 20+ security leaders who have successfully and unsuccessfully built security champions programs. Check out this playbook to learn how to run an effective developer-focused security champions program.