Skip to main content

How to secure your GitHub Actions workflows with Snyk to Enhance JavaScript Security

Written by:
0 mins read

If you manage your source code repositories on GitHub, you’re probably also taking advantage of GitHub Actions for CI/CD workflows, which presents a good opportunity to secure your JavaScript applications.

Some core workflows software developers use GitHub Actions revolve around building and testing the software artifact. It could be a frontend application that requires transpilation and TypeScript type compilation or a backend application with continuous integration testing workflows such as running unit tests, integration tests, etc.

You can use some useful auxiliary GitHub Actions workflows, like linting your Markdown files for proper formatting or catching broken links in your README.

What about adding some security tests, though? Better know early and remediate than find out too late when you’ve experienced a data breach or other security issues.

Adding Snyk security to GitHub Actions workflows

Snyk provides a pre-built custom Snyk GitHub Actions workflow that you can add to your CI and saves you the trouble of managing the vulnerability scans using the Snyk CLI directly. The code repository for the GitHub Action is found at snyk/actions on GitHub.

Get your Snyk token

To begin with, we need to obtain your Snyk token so we can add it to the GitHub Action. You can refer to Snyk GitHub Actions documentation on how to get your Snyk token. Once you’ve obtained the Snyk token, add it to the Actions repository secrets via the GitHub settings interface:

Actions secrets and variables on GitHub repository

Note: if you manage different environments within your CI workflows, defining the Snyk token as a secret per environment is safer than at the repository level.

Configure the Snyk GitHub Action workflow

Next, we can continue by creating a .github/workflows/security.yml file that will have the basic Snyk security scan workflow:

name: Security

on: [push, pull_request]

jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@main
      - name: Run Snyk to check for vulnerabilities
        uses: snyk/actions/node@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

Running the Snyk security scan

Once you’ve added the security.yml workflow file, it will get executed with an event that commits and pushes updates to the main branch or for pull request events and then performs an open source security for third-party package vulnerabilities:

Snyk security scan demonstrates GitHub Action workflow successful scan finding no security vulnerabilities in the project

Great success!

No security vulnerabilities were found for my little CLI project.

This only scans open source vulnerabilities because, by default, it executes the snyk test command line. Let’s also ensure it scans for code security issues in case I accidentally add those.

Adding SAST security code scan with Snyk 

Snyk can also scan your source code for vulnerabilities. If you mistakenly wrote insecure code or didn’t follow secure coding practices, Snyk will detect the source-to-sink code flow and advise you on how to fix it if you use the Snyk IDE extension.

Let’s add code security scanning to our GitHub Actions workflow by extending the existing job declaration with the following:

 code-security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@main
      - name: Run Snyk to check for vulnerabilities
        uses: snyk/actions/node@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
        with:
         command: code test

 You’ll notice how we specifically added a command: code test extra parameter to the Snyk GitHub Action.

How to fix code security vulnerabilities?

Snyk may detect security issues in your code or dependencies, so let’s discuss how to address them.

The following GitHub Action logs show how the Snyk action found a command injection vulnerability in my project. Snyk provides the following information:

  • File path and line number are used to detect an insecure code path. The following security workflow screenshot shows src/bin/cli.ts on line 8.

Description of the security vulnerability detected. The findings below detected a command injection vulnerability that flows from a command line argument into Nthe ode.js core module child_process

Snyk security GitHub Action finds a command injection security vulnerability in a JavaScript application project.

If you install the Snyk IDE extension, like I did on VS Code, you’ll gain the following:

  • A more thorough report of how the code security issue flows in your application

  • Find the security issues sooner while you code and not have to wait until the CI workflow runs

  • Receive suggested security advice to fix it, or in some cases, Snyk’s DCAI Fix will also provide auto-fix capabilities using Snyk’s own AI engine.

Snyk shows command injection data flow and fixed code examples.

This JavaScript project is a Node.js command-line application that receives the user's command to run and then executes it. Spawning system commands is the core use case for this Node.js CLI, and as such, it is an acceptable risk and not a security vulnerability.

To avoid Snyk detecting it as a security issue, we’re going to add a comment above the vulnerable line of code (line 8, which Snyk reported on before) that tells Snyk to ignore this issue:

8: // file deepcode ignore IndirectCommandInjection: <accepted user input for the CLI is part of how this program works>
9: const result = await runCommandAndNotify(commandToRun)

Next in application security for CI

As a follow-up resource to this article, I recommend the following read-ups:

Play Fetch the Flag

Test your security skills in our CTF event on February 27, from 9 am - 9 pm ET.