I'm so excited I've participated in SnykCon 2020! 🔥
Listening to the talks lit a fire in me, and I really want to take container security seriously from now on, knowing how much easier it is today with tools like Snyk 🚀
But after running a container scan...
... on a couple of very simple projects, well, this is not the result I was expecting: 🤯🤯🤯
This was literally an "Hello World!" type of project, what is going to happen if I scan a real project? How do I start making sense of this?
Let me do a quick introduction and then I'll show you how I practically approached this problem 😉
A modern approach to security - DevSecOps
As I learned from this year's conference, finding vulnerabilities early on in the software development cycle is paramount in this day and age.
With the adoption of Continuous Delivery, hence shorter release cycles, we can no longer afford to wait for a team of security experts to validate every release. New code will already be running in production by the time they complete their audit!
Also, developers are the best people that can contextualize the vulnerabilities, and take action to fix them. 👨🏻💻
Shifting the responsibility towards developers
Ok, this is a nice concept, developers are now responsible for security too! But hold on a sec, they're developers! How can we expect them to do their job, and also monitor their software for vulnerabilities every day?
This is where I think people at Snyk have done a great job. Their tools are focused on helping developers with:
- identifying vulnerabilities as early as in the developer's laptop
- providing command-line tools that can be integrated into CI/CD workflows
- monitoring generated artifacts to proactively notify the team when new vulnerabilities are discovered
- advise on actions to fix vulnerabilities directly in the CLI for developers to see
My experience with Snyk Container scan
Given that there's no such thing as absolute security, this is the process I followed to get as close as I could for my demo container.
If you want to have a look at the repository, you can find it here. It's a simple "Hello, World!" Python project, that, when I started, had a whopping 267 vulnerabilities!
Step 0 - creating a Snyk account
The first thing to do is to create a Snyk account. This is required to start using the CLI tools from your development machine. See below, you just need to authorize the app with one of your existing accounts
After creating the account, Snyk will generate your personal API token. This is needed to use the CLI tools from command-line and from your CI/CD workflow.
If you already have an account, you'll find the token under Your Name > General Settings > API Token
Install the CLI tools with npm
and authenticate with your token:
# Install Snyk CLI with npm
> npm install -g snyk
# Authenticate with your Snyk account
> snyk auth ${YOUR_API_TOKEN}
We're now ready to scan our project! 🚀
Step 1 - start from the development machine
As I learned in the conference, the best way is to start in your development machine using Snyk CLI.
First I wanted to make sure my python dependencies are clean from vulnerabilities. I'll do that directly from the command-line by running
> snyk test
And it immediately found an issue with my requirements.txt
file.
What's cool about this, is that Snyk tells me that the vulnerability in sqlalchemy@1.3.17
has been resolved in a later version of the package, so I will just upgrade it to the suggested version sqlalchemy@1.3.19
.
Container image scanning
Next, I want to run a container scan to make sure my image has as little vulnerabilities as possible.
To do that, I first need to build the image, and then I can immediately scan it from the command line with snyk container test
:
> snyk container test --file=Dockerfile snyk-container-demo
By using the --file=Dockerfile
we can tell Snyk which Dockerfile generated the snyk-container-demo
image. This way we'll be able to get more accurate suggestions from the advisor.
Stay calm and keep reading
This is what I told myself when I first read this report. Despite having soo many issues reported (267 to be exact), the report is also suggesting alternative images to the one I am currently using for the project:
Recommendations for base image upgrade:
Alternative image types
Base Image Vulnerabilities Severity
python:3.9.0rc1-slim 73 17 high, 12 medium, 44 low
python:3.9.0b5-slim-buster 73 17 high, 12 medium, 44 low
This is pretty nice! I can see that the -slim
and -slim-buster
versions of my base image have fewer vulnerabilities. So next thing I'll do is changing my Dockerfile
to use one of those.
And after applying the suggestion...
... I was glad to see that the number of vulnerabilities found was drastically reduced!
In this report, Snyk is also telling me that I'm currently running on the most secure version of the selected base image, remember, there's no such thing as absolute security 😅
Being happy with the base image I selected, I can commit the changes in the repo and move on with the process.
Step 2 - CI Integration
I will now integrate Snyk with my Continuous Integration workflow. I don't have any in this project yet, so I'm going to use GitHub Actions.
With a quick Google search, I found out that Snyk already published a GitHub action I can use to scan my repository on every commit and collect the results in the Security tab of the GitHub repo.
I will then copy the template provided, and create a new file in my repo in the .github/workflows
directory called secscan.yml
:
name: Container Scan
on: push
jobs:
snyk:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build the Docker image
run: docker build -t mcastellin/snyk-container-demo .
- name: Run Snyk to check Docker image for vulnerabilities
# Snyk can be used to break the build when it detects vulnerabilities.
# In this case we want to upload the issues to GitHub Code Scanning
continue-on-error: true
uses: snyk/actions/docker@master
env:
# In order to use the Snyk Action you will need to have a Snyk API token.
# More details in https://github.com/snyk/actions#getting-your-snyk-token
# or you can signup for free at https://snyk.io/login
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
image: mcastellin/snyk-container-demo
args: --file=Dockerfile --exclude-base-image-vulns
- name: Upload result to GitHub Code Scanning
uses: github/codeql-action/upload-sarif@v1
with:
sarif_file: snyk.sarif
I have pretty much used the standard values here, except for the args: --file=Dockerfile --exclude-base-image-vulns
.
By adding the --exclude-base-image-vulns
parameter we are telling Snyk not to report vulnerabilities that are introduced by Docker base image layers. This is to make sure that we are breaking the build only when we introduce new issues in the Dockerfile.
The reason for ignoring base image vulnerabilities is to avoid having too much noise in the CI scan. We have already accepted the base image so we're only interested in blocking the issues we add with our customizations.
Before committing our GitHub Action YAML file, we have to configure the secret.SNYK_TOKEN
in our registry. In the GitHub repository settings, go to Settings > Secrets > New Secret and configure the value for the Snyk token:
We can now push our changes and see the result of the security scan:
Step 3 - Breaking the build
After all the effort fixing vulnerabilities I really want to make sure nobody can introduce new ones! Let's modify our Dockerfile and open a Pull Request that introduces an insecure package: curl
, who knew!? 🤔
...
RUN apt-get update \
&& apt-get install -qqy curl \
&& rm -rf /var/lib/apt/lists
...
Found it!
And the container scan found new vulnerabilities, giving us the peace of mind, that if anyone installs dodgy packages we'll be able to catch it before merging the code into the main branch!
Step 4 - Analyzing the report
For every issue found by Snyk you'll get a very detailed report, telling you:
- what file introduced the issue
- a description of the vulnerability
- remediation advice
Wrapping up
It's been a fun couple of days for me to attend to SnykCon 2020 and I hope by sharing my first experience with Snyk and container scanning, I have also encouraged you to learn how to make the most out of these tools to keep your applications secure!
Thanks for reading! And don't forget to follow me if you want to see more content like this!
Top comments (0)