Utilizing container scanning tools for improving security

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 about the security tools and have 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)
LIBRARYVULNERABILITY IDSEVERITYINSTALLED VERSIONFIXED VERSIONTITLE
busyboxCVE-2021-42374CRITICAL1.31.1-r101.31.1-r11busybox: 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)
LIBRARYVULNERABILITY IDSEVERITYINSTALLED VERSIONFIXED VERSIONTITLE
aws-sdkCVE-2020-28472CRITICAL2.778.02.814.0Prototype Pollution via file load in aws-sdk and @aws-sdk/shared-ini-file-loader -->avd.aquasec.com/nvd/cve-2020-28472
nodemailerCVE-2020-77696.4.146.4.16Command injection in nodemailer -->avd.aquasec.com/nvd/cve-2020-7769
objectionCVE-2021-37662.2.32.2.16Prototype Pollution in objection.js -->avd.aquasec.com/nvd/cve-2021-3766
ssh2CVE-2020-263010.8.91.4.0nodejs-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. It does not separate the OS packages and 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 IDPackageSeverityFixCVERefsVulnerability URLFeed GroupPackage Path

CVE-2017-18381

mongodb-3.6.5

Critical

None

CVE-2017-18381

https://nvd.nist.gov/vuln/detail/CVE-2017-18381

npm

nvd

/wiki/node_modules/mongodb/package.json

CVE-2019-19646

sqlite-3.30.1-r2

Critical

None

CVE-2019-19646

https://nvd.nist.gov/vuln/detail/CVE-2019-19646

APKG

nvd

pkgdb

CVE-2019-19646

sqlite-libs-3.30.1-r2

Critical

None

CVE-2019-19646

https://nvd.nist.gov/vuln/detail/CVE-2019-19646

APKG

nvd

pkgdb

CVE-2020-11656

sqlite-3.30.1-r2

Critical

None

CVE-2020-11656

https://nvd.nist.gov/vuln/detail/CVE-2020-11656

APKG

nvd

pkgdb

CVE-2020-11656

sqlite-libs-3.30.1-r2

Critical

None

CVE-2020-11656

https://nvd.nist.gov/vuln/detail/CVE-2020-11656

APKG

nvd

pkgdb

CVE-2021-29940

through-2.3.8

Critical

None

CVE-2021-29940

https://nvd.nist.gov/vuln/detail/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

https://github.com/advisories/GHSA-48ww-j4fc-435p

npm

github:npm

/wiki/node_modules/nodemailer/package.json

GHSA-r659-8xfp-j327

objection-2.2.3

Critical

2.2.16

CVE-2021-3766

https://github.com/advisories/GHSA-r659-8xfp-j327

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.

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.

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).


Share this article on:

Comments