Files
containers/slides/sbom/python-app-deployment.md
Marco Verleun 5c31d64239
Some checks failed
Gitea Actions Demo Training / Explore-Gitea-Actions (push) Failing after 10s
More info
2024-02-18 13:14:35 +01:00

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

The code is not so important here

We will distribute our app in a docker container.

The following base images are used:

  • 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"]

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.