Fix the image, not the container
Task
Scan a container image, patch the running container, re-scan, and watch the finding come straight back when the container is recreated. Then fix it properly at the image and prove the difference.
Steps
- Build an image from a deliberately old base -- a distribution release a few versions behind -- with one application dependency pinned to an old version. Tag it
myapp:old. - Scan the image with an image scanner (
trivy image myapp:old) and record the finding count by severity. - Run a container from it the way a careless deployment would -- as root, with a host directory mounted:
docker run -d --name myapp-container -v /srv/lab-data:/data myapp:old sleep infinity. Inside the running container, update the vulnerable package. A scanner reads images, not running containers, so capture the container's state as one --docker commit myapp-container myapp:patched-in-place-- scan that, and confirm the finding is gone. - Now destroy the container (
docker rm -f myapp-container) and start a fresh one from the same image with the same command. Re-scanmyapp:old. The finding is back, because nothing about the image changed. - Fix it at the source: update the base image tag, rebuild as
myapp:new, re-scan the image. - Finally, look for the findings a package scanner does not produce at all -- the container running as root, a mounted host path, a secret in an environment variable -- and note which tool would have to find each.
Verify
trivy image --severity HIGH,CRITICAL --quiet myapp:old | grep -c "CVE-"
trivy image --severity HIGH,CRITICAL --quiet myapp:new | grep -c "CVE-"
docker inspect myapp-container --format '{{.Config.User}}'
docker inspect myapp-container --format '{{range .Mounts}}{{.Source}} {{end}}'
The first two must differ substantially and the difference must come from the rebuild, not from anything done inside a container. The last two are the findings no CVE scanner reports: an empty user field means the container runs as root, and a host path in the mounts is an escape route -- both are misconfigurations, and misconfigurations have no patch.
Notes
Step 4 is the one to sit with. The remediation in step 3 was real, verified, and completely worthless, because the unit of remediation in a container estate is the image and not the instance.
The same argument applies to every finding that returns after a rebuild: golden images, launch templates, infrastructure-as-code. Fixing the instance is fixing the symptom of a definition that still says the wrong thing.
This is an independent study companion for CompTIA CySA+ CS0-004 and is not produced by or endorsed by CompTIA.