Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

README.md

Container Security Scan

⏱ ~15 min · 📍 Module 4 of 7

1234567

This workshop module covers container security scanning to identify vulnerabilities in container images and configurations.

Why is Container Security Important?

Containers are now one of the most common ways to deploy applications. They are also attractive targets for attackers who can use them to access underlying infrastructure, steal secrets (including cloud credentials), or execute arbitrary code.

Container security scanning analyzes images and container configurations to identify security vulnerabilities, misconfigurations, and compliance issues before releasing them.

Common Container Security Issues

Image Vulnerabilities:

  • Image Vulnerabilities - Outdated or vulnerable dependencies, both in the base image and in the application dependencies.
  • Supply Chain - Untrusted base images. Trojanized or typo-squatted images pulled from public registries.
  • Secrets in Images - Hardcoded credentials or keys.

Configuration Issues:

  • Root User - Running containers as root
  • Excessive Privileges - Unnecessary capabilities can allow container escape.
  • Exposed Ports - Unintended network exposure
  • Missing Security Controls - No health checks or resource limits
  • Weak Network Segmentation - Overly permissive ingress rules allow lateral movement
  • Dangerous Volumes - Mounting host volumes can expose sensitive data or allow privilege escalation.

Tools Used in This Module

Tool What it does Notes
Trivy Vulnerability, misconfiguration and secret scanner for containers Also scans filesystems, IaC and repos; this module focuses on containers
Grype Fast vulnerability scanner for container images and filesystems By Anchore; uses multiple vuln DBs and generates SBOM automatically

Learning Objectives

By the end of this module, you will:

  • Understand container security risks
  • Learn to scan images for vulnerabilities
  • Understand supply chain security for containers
  • Identify Dockerfile security best practices

Tip

A clean scan can take more than one fix. Bumping the base image clears OS-package and language-runtime CVEs, but transitive dependencies bundled inside the new image (e.g., libraries shipped with the global package manager) may still surface as HIGH findings. Expect to fix in layers — re-run the scanner between each change to see what's left.

Security Checklist

  • Use minimal, trusted base images and rebuild them regularly.
  • Patch all High/Critical CVEs before shipping; fail the build if any remain.
    • Note: You can also ignore them if you verified the vulnerability is not exploitable.
  • Run containers as a non-root user with only the capabilities they truly need.
  • Remove build tools & secrets via multi-stage builds to shrink the attack surface.
  • Sign images and verify signatures at pull/admission time to ensure provenance.
  • Enable runtime protection (seccomp/AppArmor profiles, resource limits, live detection).
  • Implement health and readiness checks

References

Other Tools

  • slimtoolkit/slim: Tool to reduce the size of container images (making them more secure).

Solutions (spoilers — open only when stuck)

The container bait is the base image in code/Dockerfile — it ships with an EOL alpine that has unpatched HIGHs. The CI failure is intentional.

Trivy — alpine OS-layer HIGHs (musl, etc.)

What Trivy flagged: an alpine 3.19.4 base ships musl / musl-utils HIGHs (e.g. CVE-2025-26519, CVE-2026-40200) and EOL warnings.

Reading the output: Trivy prints a clean table (Library / Vulnerability / Severity / Status / Installed Version / Fixed Version / Title). This is the gold-standard output across the workshop.

⚠️ Don't just bump alpine minor: node:20-alpine3.19node:20-alpine3.21 actually increases the finding count (alpine 3.21 still ships an unpatched openssl). Jump to a current node-major instead.

⚠️ "Fixed Version" is per-CVE, not per-package: bumping to the version Trivy lists in that column only closes the CVE you happened to look at. Pick the latest stable image tag.

Fix — bump the base image:

-FROM node:20-alpine3.19
+FROM node:25-alpine
Grype — same root cause, terser output

What Grype reports: the Summarize findings step parses the SARIF and prints each CVE as ruleId | message | path:line to the job log — plus a helpful warning: 188 packages from EOL distro "alpine 3.19.4". The full SARIF is also uploaded to the GitHub Code Scanning tab if your fork has GHAS enabled.

Same root cause as Trivy: EOL alpine base.

Fix — identical to the Trivy fix above.