Utilizing container scanning tools for improving security
Category: security
Modified: Wed, 2022-Jan-19
Introduction
Nowadays, many applications have provided Docker container images to the users. We should not just blindly trust that all those containers are free of security problems. We should utilize various container image scanning tools for improving security. In this article, we would explore some of the open source container security tools. Note that many security tools mentioned in this article also support scanning Dockerfiles and IaC (CloudFormation and Terraform). Please also checkout my Cloud Native Wiki ,it has a summary/list about the security tools and it also has wiki pages for other topics.
Trivy
The first one on the list is Trivy by Aqua Security. Users can use access this application by CLI or by integrating with other repository application like GoHarbor. Trivy, is the the default image scanning tool for GoHarbor, replacing Clair. I found Trivy easy to use and it is very good at scanning remote container images by specifying the location of remote container repository.
$ trivy image --security-checks vuln,config -s CRITICAL --format table docker.io/requarks/wiki:2.5.219 docker.io/requarks/wiki:2.5.219 (alpine 3.11.12) ================================================ Total: 2 (CRITICAL: 2) +------------+------------------+----------+-------------------+---------------+---------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +------------+------------------+----------+-------------------+---------------+---------------------------------------+ | busybox | CVE-2021-42374 | CRITICAL | 1.31.1-r10 | 1.31.1-r11 | busybox: out-of-bounds read | | | | | | | in unlzma applet leads to | | | | | | | information leak and denial... | | | | | | | -->avd.aquasec.com/nvd/cve-2021-42374 | +------------+ + + + + + | ssl_client | | | | | | | | | | | | | | | | | | | | | | | | | | | +------------+------------------+----------+-------------------+---------------+---------------------------------------+ Node.js (node-pkg) ================== Total: 4 (CRITICAL: 4) +------------+------------------+----------+-------------------+---------------+---------------------------------------+ | LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | +------------+------------------+----------+-------------------+---------------+---------------------------------------+ | aws-sdk | CVE-2020-28472 | CRITICAL | 2.778.0 | 2.814.0 | Prototype Pollution via | | | | | | | file load in aws-sdk and | | | | | | | @aws-sdk/shared-ini-file-loader | | | | | | | -->avd.aquasec.com/nvd/cve-2020-28472 | +------------+------------------+ +-------------------+---------------+---------------------------------------+ | nodemailer | CVE-2020-7769 | | 6.4.14 | 6.4.16 | Command injection in nodemailer | | | | | | | -->avd.aquasec.com/nvd/cve-2020-7769 | +------------+------------------+ +-------------------+---------------+---------------------------------------+ | objection | CVE-2021-3766 | | 2.2.3 | 2.2.16 | Prototype Pollution in objection.js | | | | | | | -->avd.aquasec.com/nvd/cve-2021-3766 | +------------+------------------+ +-------------------+---------------+---------------------------------------+ | ssh2 | CVE-2020-26301 | | 0.8.9 | 1.4.0 | nodejs-ssh2: Command injection | | | | | | | by calling vulnerable | | | | | | | method with untrusted input | | | | | | | -->avd.aquasec.com/nvd/cve-2020-26301 | +------------+------------------+----------+-------------------+---------------+---------------------------------------+
Note the above tables are in Restructured Text format.
Click here for viewing in HTML table format (manually converted).
docker.io/requarks/wiki:2.5.219 (alpine 3.11.12) ================================================ Total: 2 (CRITICAL: 2)
LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
busybox | CVE-2021-42374 | CRITICAL | 1.31.1-r10 | 1.31.1-r11 | busybox: out-of-bounds read in unlzma applet leads to information leak and denial... -->avd.aquasec.com/nvd/cve-2021-42374 |
ssl_client |
Node.js (node-pkg) ================== Total: 4 (CRITICAL: 4)
LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
aws-sdk | CVE-2020-28472 | CRITICAL | 2.778.0 | 2.814.0 | Prototype Pollution via file load in aws-sdk and @aws-sdk/shared-ini-file-loader -->avd.aquasec.com/nvd/cve-2020-28472 |
nodemailer | CVE-2020-7769 | 6.4.14 | 6.4.16 | Command injection in nodemailer -->avd.aquasec.com/nvd/cve-2020-7769 | |
objection | CVE-2021-3766 | 2.2.3 | 2.2.16 | Prototype Pollution in objection.js -->avd.aquasec.com/nvd/cve-2021-3766 | |
ssh2 | CVE-2020-26301 | 0.8.9 | 1.4.0 | nodejs-ssh2: Command injection by calling vulnerable method with untrusted input -->avd.aquasec.com/nvd/cve-2020-26301 |
The Docker image (WikiJS) is using Alpine Linux 3.11 (out-dated!). Trivy had detected two critical security issues for the Alpine OS packages (apk). WikiJS is a NodeJS application. Trivy is able to check the NodeJS packages inside the container too. Trivy found four critical security issues for the NodeJS packages. For both cases (OS or NodeJS packages), Trivy provided the current installed versions and the version that the issue is fixed. Finally, Trivy also provided links and references that the CVE or security problem is about. Besides scanning Docker images, Trivy also supports scanning Dockerfiles, Kubernetes resources, Terraform and etc. As I had mentioned before, GoHarbor recently switched the default scanning engine from Clair to Trivy. Personally I think Trivy is handy and is pretty impressive.
Grype
Next, we have Grype by Anchore Inc.. Grype is a CLI tool. It is the scanning engine for Anchore Open Source and Anchore Enterprise security platform.
$ grype -o table docker.io/requarks/wiki:2.5.219 --only-fixed NAME INSTALLED FIXED-IN VULNERABILITY SEVERITY nodemailer 6.4.14 6.4.16 GHSA-48ww-j4fc-435p Critical objection 2.2.3 2.2.16 GHSA-r659-8xfp-j327 Critical ssh2 0.8.9 1.4.0 GHSA-652h-xwhf-q4h6 High **The output is trimmed for brevity**
Here, the output from Grype is less verbose because I am using the table format. It does not separate the OS packages and npm packages. If you use the JSON format output, it should show the package location (OS pacakages or npm packages).
I only listed the items that could be fixed and the output has been trimmed for brevity. Different scanning tools defined the severity differently. Both tools agree the NodeJS package 'nodemailer' and 'objection' has a severity of critical. Grype categorized NodeJS-ssh2 has a severity of high instead of critical.
Anchore
Anchore engine is a specialized tool for scanning container images. One of the important features of Anchore engine is that it could optionally includes ClamAV for scanning files inside the containers. Other scanning tools may only rely on the vulnerability databases to check against the package database (e.g. rpm/deb/npm) inside the container. Let’s see the output from the scanner:
$ anchore-cli image add docker.io/requarks/wiki:2.5.219
$ anchore-cli image vuln docker.io/requarks/wiki:2.5.219 all | grep Critical \
| awk -F ' ' '{print "|"$1"|"$2"|"$3"|"$4"|"$5"|"$6"|"$7"|"$8"|"$9}'
The default output format is plain text without any separators. I have added it and perform some table formatting in the article.
Vulnerability ID | Package | Severity | Fix | CVE | Refs | Vulnerability URL | Feed Group | Package Path |
---|---|---|---|---|---|---|---|---|
CVE-2017-18381 | mongodb-3.6.5 | Critical | None | CVE-2017-18381 | npm | nvd | /wiki/node_modules/mongodb/package.json | |
CVE-2019-19646 | sqlite-3.30.1-r2 | Critical | None | CVE-2019-19646 | APKG | nvd | pkgdb | |
CVE-2019-19646 | sqlite-libs-3.30.1-r2 | Critical | None | CVE-2019-19646 | APKG | nvd | pkgdb | |
CVE-2020-11656 | sqlite-3.30.1-r2 | Critical | None | CVE-2020-11656 | APKG | nvd | pkgdb | |
CVE-2020-11656 | sqlite-libs-3.30.1-r2 | Critical | None | CVE-2020-11656 | APKG | nvd | pkgdb | |
CVE-2021-29940 | through-2.3.8 | Critical | None | CVE-2021-29940 | npm | nvd | /usr/local/lib/node_modules/npm/node_modules/through/package.json | |
GHSA-48ww-j4fc-435p | nodemailer-6.4.14 | Critical | 6.4.16 | CVE-2020-7769 | npm | github:npm | /wiki/node_modules/nodemailer/package.json | |
GHSA-r659-8xfp-j327 | objection-2.2.3 | Critical | 2.2.16 | CVE-2021-3766 | npm | github:npm | /wiki/node_modules/objection/package.json |
The presentation format (just plain text separated by spaces) from Anchore CLI is not cool, but the content is great. Anchore engine could show exactly which NodeJS package.json files have security problems. Also, it provides the references about the related CVE. Here, Anchore engine also agreed that the NodeJS packages 'nodemail' and 'objection' have critical vulnerabilities. By the way, it also detected the NPM package 'through' has critical vulnerabilities, which Trivy and Grype did not categorize them as critical. Finally, one of the downside of Anchore engine is that the CLI is not a light weight single (Golang) binary. It needs to be deployed on Docker or Kubernetes.
Now, we had come across three container image scanning tools. Let’s take a look on other tools for scanning Dockerfiles (not the same as scanning Docker images).
Checkov
Checkov by Bridgecrew. Checkov is more focused on IaC, it supports Terraform (major cloud providers), AWS CloudFormation, Azure Resource Manager (ARM), Kubernetes resources and Dockerfiles. Checkov is written in Python and is slower than other security scanning tools. It checks for IaC files and perform security checking and recommendations about security best practices. Users can integrate the scanning result with the Bridgecrew web console.
Here’s the output of scanning a Dockerfile by Checkov.
$ checkov --framework dockerfile -f ./Dockerfile _ _ ___| |__ ___ ___| | _______ __ / __| '_ \ / _ \/ __| |/ / _ \ \ / / | (__| | | | __/ (__| < (_) \ V / \___|_| |_|\___|\___|_|\_\___/ \_/ By bridgecrew.io | version: 2.0.589 dockerfile scan results: Passed checks: 5, Failed checks: 1, Skipped checks: 0 Check: CKV_DOCKER_1: "Ensure port 22 is not exposed" PASSED for resource: ./Dockerfile. File: ./Dockerfile:1-54 Guide: https://docs.bridgecrew.io/docs/ensure-port-22-is-not-exposed Check: CKV_DOCKER_7: "Ensure the base image uses a non latest version tag" PASSED for resource: ./Dockerfile. File: ./Dockerfile:1-54 Guide: https://docs.bridgecrew.io/docs/ensure-the-base-image-uses-a-non-latest-version-tag Check: CKV_DOCKER_8: "Ensure the last USER is not root" PASSED for resource: ./Dockerfile.USER File: ./Dockerfile:45-45 Guide: https://docs.bridgecrew.io/docs/ensure-the-last-user-is-not-root Check: CKV_DOCKER_5: "Ensure update instructions are not use alone in the Dockerfile" PASSED for resource: ./Dockerfile. File: ./Dockerfile:1-54 Guide: https://docs.bridgecrew.io/docs/ensure-update-instructions-are-not-used-alone-in-the-dockerfile Check: CKV_DOCKER_3: "Ensure that a user for the container has been created" PASSED for resource: ./Dockerfile.USER File: ./Dockerfile:45-45 Guide: https://docs.bridgecrew.io/docs/ensure-that-a-user-for-the-container-has-been-created Check: CKV_DOCKER_2: "Ensure that HEALTHCHECK instructions have been added to container images" FAILED for resource: ./Dockerfile. File: ./Dockerfile:1-54 Guide: https://docs.bridgecrew.io/docs/ensure-that-healthcheck-instructions-have-been-added-to-container-images
So Checkov checked the Dockerfile and provided the recommendation and security best practices. However, it would not check the content of the container image. So, it would not check container images against the vulnerabilities databases.
Kics
Kics by Checkmarx is another tool focused on IaC. It supports checking resources like Dockerfiles, Ansible, Terraform, AWS CloudFormation, Kubernetes resources and Helm.
Here is part the output of scanning a Dockerfile by Kics.
Healthcheck Instruction Missing, Severity: LOW, Results: 2 Description: Ensure that HEALTHCHECK is being used. The HEALTHCHECK instruction tells Docker how to test a container to check that it is still working Platform: Dockerfile [1]: Dockerfile:4 003: # ==================== 004: FROM node:14-alpine AS assets 005: [2]: Dockerfile:4 003: # ==================== 004: FROM node:14-alpine AS assets 005: Unpinned Package Version in Apk Add, Severity: MEDIUM, Results: 2 Description: Package version pinning reduces the range of versions that can be installed, reducing the chances of failure due to unanticipated changes Platform: Dockerfile [1]: Dockerfile:29 028: 029: RUN apk add bash curl git openssh gnupg sqlite --no-cache && \ 030: mkdir -p /wiki && \ [2]: Dockerfile:6 005: 006: RUN apk add yarn g++ make python --no-cache 007:
So, it is similar to Checkov. Kics provides recommendation and best practices for security measures.
Dockle
Dockle is a linter for Docker images. It is especially good at finding un-necessary files and SGID/SUID files. But it would not check for the vulernabilites of packages against a database.
Here is part the output of scanning a Docker image by Dockle. As you can see there are some leftover files (ssh private keys for testing) and Dockerfile(s) left inside the image. Also, it reminds that the Docker Content Trust is not enabled.
$ dockle docker.io/requarks/wiki:2.5.219 FATAL - CIS-DI-0010: Do not store credential in environment variables/files * Suspicious filename found : wiki/node_modules/ssh2/test/fixtures/id_dsa (You can suppress it with "-af id_dsa") * Suspicious filename found : wiki/node_modules/ssh2/test/fixtures/id_ecdsa (You can suppress it with "-af id_ecdsa") * Suspicious filename found : wiki/node_modules/ssh2/test/fixtures/id_rsa (You can suppress it with "-af id_rsa") INFO - CIS-DI-0005: Enable Content trust for Docker * export DOCKER_CONTENT_TRUST=1 before docker pull/build INFO - CIS-DI-0006: Add HEALTHCHECK instruction to the container image * not found HEALTHCHECK statement INFO - DKL-LI-0003: Only put necessary files * unnecessary file : wiki/node_modules/getos/Dockerfile * unnecessary file : wiki/node_modules/getos/tests/debian/7.3/Dockerfile * unnecessary file : wiki/node_modules/getos/tests/debian/7.4/Dockerfile
Other products
Below are some of the open source security scanning tools.
Clair (for images)
Originally Clair was developed by CoreOS. Clair focused on scanning container images, it works great with the Quay repository. There is effort to make use of Clair as a CLI tool. But the scanner CLI tool currently only supports Clair V2. Now, Clair has active development with the version 4. We may update the article if Clair V4 could be used more conveniently as a CLI tool. You may want to check out Quay.io. Quay.io has integrated Clair with it.
Snyk (for images and IaC)
Snyk supports IaC resources (not supporting Ansible), AWS CloudFormation, Kubernetes (YAML) and Docker images. One of the distinctive features of Snyk is that it supports static code analysis for major programming languages.
Terrascan (for IaC)
Terrascan was developed by Accurics, which Accurics was also acquired by Tenable. It supports static code analysis on Terraform, Kubernetes (YAML), Helm, Dockerfile and cloud resources.
Deepfence ThreatMapper (for Docker, Kubernetes and Fargate serverless)
ThreatMapper was originally a closed source application. Deepfence made the application to be became open source in 2021 Oct. On the roadmap is OpenSCAP support, CIS/NIST/PCI-DSS profiles support and etc. This product focused on runtime scanning of VMs and pods. It uses runtime contexts like network traffic to determine exploitability and attack paths.
So, the nature of this tool is not the same as we had seen before in the article (CLI based or scanning by schedulers). But I mention this unqiue tool in this article because it is an open source product. Finally, we thank Deepfence CTO and from Deepfence Twitter for their comments.
Neuvector
Edit: Neuvector is opensourced by Suse on January 2022 (also have commericial offerings). Neuvector is full life cycle security platform for cloud native security and container platform. It has scanning container capability and it also featured a Layer 7 firewall.
Conclusion
We have come across several security scanning tools for container images. These tools are useful and they can improve the Cloud Security Posture Management (CSPM).
Comments
No. of comments: 0
Please read and agree the privacy policy before using the comment system.