paazmaya.fi

The Website of Juga Paazmaya | Stories about Web Development, Japanese Martial Arts, Hardware prototyping and travelling

Reducing vulnerabilities in Docker containers

Recently I was learning about the Chainguard tooling for reducing vulnerabilities in containers.

It started via their course, which was announced few days ago in 14th February 2024 at “New Chainguard Academy course: Painless Vulnerability Management”. It is currently free of charge, but might change at some point.

Chainguard is also providing Docker images that have dramatically reduced the number of known vulnerabilities, that can be seen for example here “Vulnerability Comparison: rust”.

In order to know what to change if there are vulnerabilities, first those vulnerabilities need to be found.

Scan images to find known vulnerabilities

Three scanners were mentioned in the course:

Scanning rust:alpine image as an example. The image is available at Docker Hub, where it is noted under “Vulnerabilities” section:

No Vulnerabilities Found

However running the scanner grype rust:alpine, reveals the following results:

✔ Cataloged contents
  ├── ✔ Packages                        [29 packages]
  ├── ✔ File digests                    [1,067 files]
  ├── ✔ File metadata                   [1,067 locations]
  └── ✔ Executables                     [105 executables]
✔ Scanned for vulnerabilities     [13 vulnerability matches]
  ├── by severity: 0 critical, 1 high, 12 medium, 0 low, 0 negligible
  └── by status:   0 fixed, 13 not-fixed, 0 ignored

NAME           INSTALLED   FIXED-IN  TYPE  VULNERABILITY   SEVERITY
binutils       2.41-r0               apk   CVE-2023-25584  High
busybox        1.36.1-r15            apk   CVE-2023-42366  Medium
busybox        1.36.1-r15            apk   CVE-2023-42365  Medium
busybox        1.36.1-r15            apk   CVE-2023-42364  Medium
busybox        1.36.1-r15            apk   CVE-2023-42363  Medium
busybox-binsh  1.36.1-r15            apk   CVE-2023-42366  Medium
busybox-binsh  1.36.1-r15            apk   CVE-2023-42365  Medium
busybox-binsh  1.36.1-r15            apk   CVE-2023-42364  Medium
busybox-binsh  1.36.1-r15            apk   CVE-2023-42363  Medium
ssl_client     1.36.1-r15            apk   CVE-2023-42366  Medium
ssl_client     1.36.1-r15            apk   CVE-2023-42365  Medium
ssl_client     1.36.1-r15            apk   CVE-2023-42364  Medium
ssl_client     1.36.1-r15            apk   CVE-2023-42363  Medium

The output from running trivy image rust:alpine states that there would be no vulnerabilities:

rust:alpine (alpine 3.19.1)

Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)

The third scanner results after running scorecard --repo=github.com/rust-lang/docker-rust this output:

RESULTS
-------
Aggregate score: 5.8 / 10

Check scores:
|---------|------------------------|--------------------------------|
|  SCORE  |          NAME          |             REASON             |
|---------|------------------------|--------------------------------|
| 10 / 10 | Binary-Artifacts       | no binaries found in the repo  |
|---------|------------------------|--------------------------------|
| 0 / 10  | Branch-Protection      | branch protection not enabled  |
|         |                        | on development/release         |
|         |                        | branches                       |
|---------|------------------------|--------------------------------|
| 1 / 10  | CI-Tests               | 2 out of 12 merged PRs         |
|         |                        | checked by a CI test -- score  |
|         |                        | normalized to 1                |
|---------|------------------------|--------------------------------|
| 0 / 10  | CII-Best-Practices     | no effort to earn an OpenSSF   |
|         |                        | best practices badge detected  |
|---------|------------------------|--------------------------------|
| 8 / 10  | Code-Review            | found 2 unreviewed changesets  |
|         |                        | out of 14 -- score normalized  |
|         |                        | to 8                           |
|---------|------------------------|--------------------------------|
| 10 / 10 | Contributors           | 17 different organizations     |
|         |                        | found -- score normalized to   |
|         |                        | 10                             |
|---------|------------------------|--------------------------------|
| 10 / 10 | Dangerous-Workflow     | no dangerous workflow patterns |
|         |                        | detected                       |
|---------|------------------------|--------------------------------|
| 0 / 10  | Dependency-Update-Tool | no update tool detected        |
|---------|------------------------|--------------------------------|
| 0 / 10  | Fuzzing                | project is not fuzzed          |
|---------|------------------------|--------------------------------|
| 0 / 10  | License                | license file not detected      |
|---------|------------------------|--------------------------------|
| 10 / 10 | Maintained             | 21 commit(s) out of 30 and 1   |
|         |                        | issue activity out of 30 found |
|         |                        | in the last 90 days -- score   |
|         |                        | normalized to 10               |
|---------|------------------------|--------------------------------|
| ?       | Packaging              | no published package detected  |
|---------|------------------------|--------------------------------|
| 0 / 10  | Pinned-Dependencies    | dependency not pinned by hash  |
|         |                        | detected -- score normalized   |
|         |                        | to 0                           |
|---------|------------------------|--------------------------------|
| 0 / 10  | SAST                   | SAST tool is not run on all    |
|         |                        | commits -- score normalized to |
|         |                        | 0                              |
|---------|------------------------|--------------------------------|
| 10 / 10 | Security-Policy        | security policy file detected  |
|---------|------------------------|--------------------------------|
| ?       | Signed-Releases        | no releases found              |
|---------|------------------------|--------------------------------|
| 10 / 10 | Token-Permissions      | GitHub workflow tokens follow  |
|         |                        | principle of least privilege   |
|---------|------------------------|--------------------------------|
| 10 / 10 | Vulnerabilities        | no vulnerabilities detected    |
|---------|------------------------|--------------------------------|

Further documentation for each of the checks is available at the scanners GitHub repository.

Mitigate known vulnerabilities

The first scanner used above, grype found one high severity level vulnerability in which I will focus here:

binutils       2.41-r0               apk   CVE-2023-25584  High

The CVE specific information is available at cve.org, but in this case not much more than just this description:

An out-of-bounds read flaw was found in the parse_module function in bfd/vms-alpha.c in Binutils.

NIST has a bit more details on the given CVE.

The fix was made already in December 2022, while the CVE was created in September 2023. Process takes time, but good news is that the fix has been there for long.

Looking at the Alpine Linux packages repository, the version 2.42-r0 is already available for binutils, but only as recently as 2024-02-19…

Given that the scanner container was a Docker image, which most likely would be used as a base for building something in a Dockerfile, so the mitigation in this case could be to update the dependencies with apk.

# Use Alpine Linux as a base with Rust tools
FROM rust:alpine

# Upgrade Alpine Linux dependencies
RUN apk upgrade --no-cache

Trying this out:

docker build . -t rust-alpine-upgrade-apk-binutils
grype rust-alpine-upgrade-apk-binutils

Start the Docker container to check which version of binutils has been taken in use

docker run -it rust-alpine-upgrade-apk-binutils busybox
apk info -vv | grep binutils

Surprisingly this still prints out the same version as found earlier:

binutils-2.41-r0 - Tools necesary to build programs

What also happened in this case, was that few days later when continuing on this topic, the CVE for binutils version 2.41-r0 was no longer shown via grype rust:alpine