Skip to main content

Supply Chain Attack - Docker

Need

Ensuring secure and verifiable supply chain for Docker dependencies

Context

  • Usage of Python 3.11.5 for developing Python applications
  • Usage of Flask version 2.3.3 for building web applications in Python

Description

Non compliant code

# Dockerfile
FROM python:3.11.5

WORKDIR /app

COPY . /app

RUN pip install Flask==2.3.3

CMD ["python", "app.py"]

In the Dockerfile above, we are creating a Docker image for a Flask application with Python 3.11.5 and Flask 2.3.3.

The vulnerability lies in the FROM python:3.11.5 line. Here, we are using the python:3.11.5 Docker image as the base image for our Docker build. However, we are not pinning this dependency to an exact digest. This means that we are not verifying the integrity of the python:3.11.5 image. If a malicious actor were to gain control of the python:3.11.5 image, they could insert malicious components into it. When we build our Docker image, we would unknowingly include these malicious components in our Docker image.

Similarly, the RUN pip install Flask==2.3.3 line installs Flask 2.3.3 into our Docker image. Again, we are not verifying the integrity of the Flask 2.3.3 package. If a malicious actor were to gain control of the Flask 2.3.3 package, they could insert malicious code into it. When we install Flask 2.3.3 into our Docker image, we would unknowingly include this malicious code in our Docker image.

This vulnerability is known as a Supply Chain Attack. In a Supply Chain Attack, a malicious actor compromises a component in a software supply chain (in this case, the python:3.11.5 Docker image and the Flask 2.3.3 package), and leverages this compromise to attack downstream consumers of this component (in this case, our Docker image).

Steps

  • Pin the exact version of the base image in the Dockerfile.
  • Use a specific version of Python instead of using the latest version.
  • Avoid using the tag latest.
  • Pin the exact version of Flask in the Dockerfile.
  • Verify the integrity of the dependencies by using mechanisms such as git-commits, artifacts, and hashes.
  • Regularly update and patch the dependencies to ensure the latest security fixes.
  • Implement a secure supply chain process to prevent supply chain attacks.

Compliant code

# Dockerfile
FROM python@sha256:8a164692c20c8f51986d25c16caa6bf03bde14e4b6e6a4c06b5437d5620cc96c

WORKDIR /app

COPY . /app

RUN pip install Flask==2.3.3

USER 1001

CMD ["python", "app.py"]

This Dockerfile is used to build a Docker image for a Flask application. The base image is a specific version of Python (3.11.5) and its integrity is verified using a SHA256 digest. The Flask version is also pinned to a specific version (2.3.3) to ensure the integrity and stability of the application. The Dockerfile also specifies a non-root user (user with ID 1001) to run the application, which is a good practice to enhance the security of the Docker container.

References