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. .. _`Moodle`: https://curs.upb.ro Tasks ----- Download the `session task archive`_. .. _`session task archive`: http://elf.cs.pub.ro/sis/res/12-supply-chain.tar Cosign ^^^^^^ Container Check """"""""""""""" Install ``cosign`` using the instructions `here _`. 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: #. If you don't have one, create an account on `DockerHub`_. #. `Install Docker `_ locally on your system #. Log in on ``docker.io``: :: docker login docker.io -u -p Now, let's push an image on `DockerHub`_. #. Create a Docker image entry on `DockerHub`_. Give it a name of your choosing. #. Create a container image from the ``Dockerfile`` provided: :: make -f Makefile.docker build #. 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 /:latest #. Test the image: :: docker run /:latest #. Push the image to `DockerHub`_: :: docker push /:latest #. Check the image in the `DockerHub`_ interface. Make sure the image is public. Now, let's sign the image. #. Sign the image using the command: :: ./cosign-linux-amd64 sign /:latest You will be prompted with an authentication screen. Choose the engine you want to use to authenticate. #. Verify the image. If you don't know your identity and issuer, you can use a regex: :: ./cosign-linux-amd64 verify /:latest --certificate-identity-regexp='.*' --certificate-oidc-issuer-regexp='.*' #. 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 /: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. .. _`DockerHub`: https://hub.docker.com/ 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``.