How to secure your GitHub Actions workflows with Snyk to Enhance JavaScript Security
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:
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:
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
.
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.
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:
If your team does Java development, I recommend sharing with them the following: Building a secure CI/CD pipeline with GitHub Actions for your Java Application
If you maintain npm packages and publish them to the npm registry, I recommend the following: GitHub Actions to securely publish npm packages.
How do you ignore Snyk issues if some issues are false positives or if you want to accept the risk?
Play Fetch the Flag
Test your security skills in our CTF event on February 27, from 9 am - 9 pm ET.