Software Supply Chain Security

We talk about how easy it is to use automatic scanning tools (both as a sysadmin and as an attacker), but also how those might miss critical security aspects. Automatic scanning tools are not the solution to everything. They do help with assessing the security of a target, but they do not always end up finding everything.

Feedback

In order to improve the SIS course, your opinions and suggestions are important to us. The feedback is anonymous and the results will only become visible after the final exam. The link to the feedback form is part of the main page of the Moodle instance for your master’s program SIS class.

Tasks

Download the session task archive.

Cosign

Container Check

Install cosign using the instructions here <https://github.com/sigstore/cosign?tab=readme-ov-file#installation>_.

Check the signature of the image we already uploaded on DockerHub:

./cosign-linux-amd64 verify razvandeax/my-hello --certificate-identity='razvan.deaconescu@upb.ro' --certificate-oidc-issuer='https://github.com/login/oauth'

Run the image locally:

docker run razvandeax/my-hello

We use cosign to validate the contents of a container we have previously uploaded. The identity and issuer are GitHub as we used GitHub to authenticate and sign.

We will use similar steps to sign new containers.

Tutorial

Open the session task archive and access the cosign/ directory. The aim is to sign and provide signed containers.

Follow the steps below:

  1. If you don’t have one, create an account on DockerHub.

  2. Install Docker locally on your system

  3. Log in on docker.io:

    docker login docker.io -u <username> -p <password>
    

Now, let’s push an image on DockerHub.

  1. Create a Docker image entry on DockerHub. Give it a name of your choosing.

  2. Create a container image from the Dockerfile provided:

    make -f Makefile.docker build
    
  3. Tag the image with the name you choose prefixed by your username. First find the image name / ID:

    docker image ls
    

    And then tag it:

    docker tag <ID_from_above> <username>/<name_of_your_choosing>:latest
    
  4. Test the image:

    docker run <username>/<name_of_your_choosing>:latest
    
  5. Push the image to DockerHub:

    docker push <username>/<name_of_your_choosing>:latest
    
  6. Check the image in the DockerHub interface. Make sure the image is public.

Now, let’s sign the image.

  1. Sign the image using the command:

    ./cosign-linux-amd64 sign <username>/<name_of_your_choosing>:latest
    

    You will be prompted with an authentication screen. Choose the engine you want to use to authenticate.

  2. Verify the image. If you don’t know your identity and issuer, you can use a regex:

    ./cosign-linux-amd64 verify <username>/<name_of_your_choosing>:latest --certificate-identity-regexp='.*' --certificate-oidc-issuer-regexp='.*'
    
  3. Ask other colleagues to verify your image. Ask them to use cosign to verify it. And ask them to use docker run to test it:

    docker run <username>/<name_of_your_choosing>:latest
    

Another Container

Use the example Dockerfile to create another minimalistic application. Aim to build a Go, C++, Rust, Dlang application.

Copy only the required libraries in a scratch container.

Follow the steps above to:

  • Create a new container.

  • Run it locally.

  • Push the container on DockerHub.

  • Sign the container with cosign.

  • Verify the container. Ask colleagues to verify it.

GitHub Container Registry (GHCR)

Use GitHub Container Registry (GHCR) instead of DockerHub.

You need a GitHub account and a personal access token with it.

You need to login to ghcr.io:

echo $PAT | docker login ghcr.io -u yokawasa --password-stdin

where $PAT is the personal access token.

Follow instructions in this article or this other article to push the container created above to GHCR.

Sign the container on GCHR.

Make the container public. You need to attach it to a repository.

Verify the container. Ask colleagues to verify it.

Syft & Grype

Install syft using the install instructions.

Use it to extract the SBOM for the following containers:

  • alpine

  • gcc:13.2

  • debian:bookworm

  • node:21-bookworm

  • node:21-alpiner3.18

  • rust:1.75-bookworm

Use it to extract the SBOM for the container you created above. Why aren’t there any items output?

Use syft to extract the SBOM in JSON format.

Install grype using the corresponding install instructions. Use it to scan for vulnerabilities of the above images.

Create your own container for two of the three options below:

  • a NodeJS framework / application of choice that uses npm

  • a Rust framework / application of choice that uses Cargo

  • a Python framework / application of choice that uses Poetry or requirements.txt

Extract the SBOM using syft. Look for vulnerabilities using grype.