Scan for NPM Vulnerabilities using Github Actions

NPM helps notify you have vulnerable dependencies by printing out a message during installation. At times, this isn’t enough. It is very easy to ignore these messages and commonly security becomes a low priority. In this tutorial, I will show you how to setup a script for checking if there are vulnerabilities and a automatic way of running it using Github Actions. Github Actions is a way to setup continuous delivery and this would work with other methods (Ex. Jenkins pipelines).

Getting Started

To start off, you will need to have a NPM project. I will use react-gh-pages as my starting code base. I will put this into a new repository and clone it to my local.

Screenshot of Github Workflow Running

Scan for Vulnerabilities

Next, we will setup the script that will scan for vulnerabilities. When you do an npm install, the file stdout line is something like this:

found 93 vulnerabilities (70 low, 22 moderate, 1 high)

We can capture the npm install stdout and check if there are any issues. Create a new file with this path and name:

scripts/pipeline/scan_for_vulnerabilities.sh

Inside this file, put the following code.

# Creates a file to capture standard out
rm -rf npm_install_output.txt
touch npm_install_output.txt

# Run NPM install (Mentions vulnerabilities at the end). Output goes into file.
npm install >> npm_install_output.txt

# Catch all vulnerabilities
# search_term="found [0-9]{1,6} vulnerabilities ([0-9]{1,6} low, [0-9]{1,6} moderate, [0-9]{1,6} high)"

# Only high vulnerabilities
search_term=", [0-9]{1,6} high)"

if grep -REo "$only_high_vulnerabilities" npm_install_output.txt
then
  if ! grep -o "found 0 vulnerabilities" npm_install_output.txt
  then
    echo "Yes, security vulnerabilities found."
    exit 1
  fi
fi

echo "No, security vulnerabilities found."

In the script, we remove previous stdout and create an empty. It will search a message containing high vulnerabilities. If the search term is found, it exits with a code higher than 0. This will cause a pipeline to fail.

You can test this out by running

bash scripts/pipeline/scan_for_vulnerabilities.sh

Setting Up Github Actions

You will need to setup a workflow in your Github Actions folder. The file path will look something like

.github/workflows/master.yml

And in this file, you will have

name: MasterDeployCI
on:
  push:
    branches:
      - master
jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [10.x]
    steps:
    - uses: actions/checkout@v1
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}
    - name: Scan for Vulnerabilities
      run: bash scripts/pipeline/scan_for_vulnerabilities.sh

To explain this script, there are few parts. The trigger is the on push events to master. This is in the first few lines of the workflow.

After, we select to run in a Ubuntu environment and select our Node version. In the steps, we checkout the code, setup node, and execute our script.

You can push this to your repository and see Github actions run.

Screenshot of Github Workflow Running

To demo a fixed solution run

npm audit fix --force

Push those changes and it will resolve the critical failures. (This is only to demo the happy solution).

Screenshot of Github Workflow Running

Thanks for reading!