5.6 KiB
Back to our app: worker.py
Let's follow our app from code to deployment in a container.
During each step we'll analyze the software and show some highlights.
Step 1: The code
import logging
import os
from redis import Redis
import requests
import time
...
redis = Redis("redis")
...
def work_loop(interval=1):
deadline = 0
loops_done = 0
while True:
if time.time() > deadline:
log.info("{} units of work done, updating hash counter"
.format(loops_done))
redis.incrby("hashes", loops_done)
loops_done = 0
deadline = time.time() + interval
work_once()
loops_done += 1
if __name__ == "__main__":
while True:
try:
work_loop()
except:
log.exception("In work loop:")
log.error("Waiting 10s and restarting.")
time.sleep(10)
Shipping the app.
We will distribute our app in a docker container.
The following base images are used to see which would be the best image for our app. We have already determined that the app will run fine with all the mentioned images:
- python:alpine
- python:3.9.18-slim
- python:latest
Building the container images
The container build is done with a small Dockerfile.
The only thing that changes is the FROM line where different base images are specified:
FROM python:latest
RUN pip install redis
RUN pip install requests
COPY worker.py /
CMD ["python", "worker.py"]
FROM python:alpine
RUN pip install redis
RUN pip install requests
COPY worker.py /
CMD ["python", "worker.py"]
Build result
The build result is as follows:
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
worker 3.9.18-slim 47f85c518f2d 7 seconds ago 237MB
worker alpine 890af8c86632 About a minute ago 110MB
worker latest 9011701a671b 3 minutes ago 1.49GB
SBOM creation
SBOM's are create from the source code and the images for further analyses.
The tool used is syft, but it could have been another tool as well.
Analysis is done with grype because it produces output that fits nice in this presentation.
Let's see how each step adds vulnerabilities. Note that the number of reported CVE's was correct at the time of writing. Quite likely more CVE's have been discoverd since then.
Source code analysis:
The source code is quite clean. Only one CVE is reported:
grype --add-cpes-if-none sbom-worker.py.json
✔ Vulnerability DB [no update available]
✔ Scanned for vulnerabilities [1 vulnerability matches]
├── by severity: 0 critical, 0 high, 1 medium, 0 low, 0 negligible
└── by status: 1 fixed, 0 not-fixed, 0 ignored
Our first image based on python:latest
This is the most tempting image. It seems to be very complete, but maybe it contains to much?
grype --add-cpes-if-none sbom-python-latest.json
✔ Vulnerability DB [no update available]
✔ Scanned for vulnerabilities [1700 vulnerability matches]
├── by severity: 21 critical, 359 high, 519 medium, 73 low, 721 negligible (7 unknown)
└── by status: 448 fixed, 1252 not-fixed, 0 ignored
Wow... We went from only 1 CVE to 1700...
Can we do better: python:3.9.18-slim
A slim image with more than enough to run our application, but much less than python:default.
grype --add-cpes-if-none sbom-python-3.9.18-slim.json
✔ Vulnerability DB [no update available]
✔ Scanned for vulnerabilities [101 vulnerability matches]
├── by severity: 1 critical, 11 high, 28 medium, 3 low, 55 negligible (3 unknown)
└── by status: 14 fixed, 87 not-fixed, 0 ignored
That's already a huge difference. Especially when you pay attention to the critical and high rated CVE's
Let's try one more image: python:alpine
grype --add-cpes-if-none sbom-python-alpine.json
✔ Vulnerability DB [no update available]
✔ Scanned for vulnerabilities [21 vulnerability matches]
├── by severity: 0 critical, 1 high, 18 medium, 0 low, 0 negligible (2 unknown)
└── by status: 9 fixed, 12 not-fixed, 0 ignored
Summary
The scores are shown in the table below.
| Source | Critial | High | Medium | Low |
|---|---|---|---|---|
| worker.py | 0 | 0 | 1 | 0 |
| python-latest | 21 | 359 | 519 | 73 low |
| python:3.9.18-slim | 1 | 11 | 28 | 3 low |
| python:alpine | 0 | 1 | 18 | 0 low |
Any idea which image I prefer to deploy?
Storing SBOM files
If you store these SBOM's files you can quickly evaluate if new CVE's are introduced without scanning every component or image again.
Or you can store them in a database like Dependency Track which will periodically evaluate the vulnerabilities and, if configured, send you notifications when your attention is required.
Distributing SBOM files
The federal US government expects vendors to provide SBOM files prior to purchasing software or appliances. And they are not alone.
On github.com you'll see them appear as well, waiting for you to download them.
Even the new standard for container registries allows you to store SBOM information. The docker buildx command can do this as well.
Final words
When working with SBOM tools make sure you're using good ones. When in doubt compare tools and see if the meet your needs. Some are good for source code, others can only identify os components and some can do both. Not all are equally good...