dotnet / dotnet-docker

Docker images for .NET and the .NET Tools.
https://hub.docker.com/_/microsoft-dotnet
MIT License
4.47k stars 1.94k forks source link

CIS-DI-0009 violation in all dotnet images under focal tag #4209

Closed ThorstenHans closed 1 year ago

ThorstenHans commented 1 year ago

Describe the Bug

.NET container images using one of the focal tags violate CIS-DI-009 benchmark rule. Non of the base images was violating this rule a couple of weeks ago.

I went through all the container images down the path and recognized that the violation is already in ubuntu.azurecr.io/ubuntu:focal. That said, I was not able to find the Dockerfile used to create ubuntu.azurecr.io/ubuntu:focal šŸ˜ž

I use latest (v.0.4.9) of dockle to lint container images.

Steps to Reproduce

This can easily be validated using the following steps:

# Create a Dockerfile 
echo "FROM ubuntu.azurecr.io/ubuntu:focal" > Dockerfile

# Build the image
docker build . -t test:0.0.1

# Lint the image using dockle
dockle test:0.0.1

FATAL   - CIS-DI-0009: Use COPY instead of ADD in Dockerfile
    * Use COPY : /bin/sh -c #(nop) ADD file:5dfb5928594745d5de89f61e7104168b42696281bc24f1ce9047bbb688387771 in /

Output of docker version

Docker version 20.10.20, build 9fdeb9c

Output of docker info

Client:
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc., v0.9.1)
  compose: Docker Compose (Docker Inc., v2.12.0)
  dev: Docker Dev Environments (Docker Inc., v0.0.3)
  extension: Manages Docker extensions (Docker Inc., v0.2.13)
  sbom: View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc., 0.6.0)
  scan: Docker Scan (Docker Inc., v0.21.0)

Server:
 Containers: 10
  Running: 2
  Paused: 0
  Stopped: 8
 Images: 174
 Server Version: 20.10.20
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 9cd3357b7fd7218e4aec3eae239db1f68a5a6ec6
 runc version: v1.1.4-0-g5fd4c4d
 init version: de40ad0
 Security Options:
  seccomp
   Profile: default
  cgroupns
 Kernel Version: 5.15.49-linuxkit
 Operating System: Docker Desktop
 OSType: linux
 Architecture: x86_64
 CPUs: 6
 Total Memory: 15.64GiB
 Name: docker-desktop
 ID: HSSH:F7ZU:VXIQ:DZQT:6UH3:TRDV:RGTS:ASCF:ICA6:4PJY:226I:POCY
 Docker Root Dir: /var/lib/docker
 Debug Mode: true
  File Descriptors: 50
  Goroutines: 52
  System Time: 2022-11-15T09:58:01.485148741Z
  EventsListeners: 3
 HTTP Proxy: http.docker.internal:3128
 HTTPS Proxy: http.docker.internal:3128
 No Proxy: hubproxy.docker.internal
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  hubproxy.docker.internal:5000
  127.0.0.0/8
 Live Restore Enabled: false
mthalman commented 1 year ago

This looks to be a false positive from the dockle tool. I would suggest logging an issue at https://github.com/goodwithtech/dockle instead.

We had recently switched over from the Ubuntu images hosted on Docker Hub to the Ubuntu image's hosted on Canonical's ACR: ubuntu.azurecr.io. That change resulted in the difference you're seeing. But when you look at the images, they are essentially the same with respect to the usage of the ADD instruction.

> docker history ubuntu:focal
IMAGE          CREATED       CREATED BY                                      SIZE      COMMENT
680e5dfb52c7   3 weeks ago   /bin/sh -c #(nop)  CMD ["bash"]                 0B
<missing>      3 weeks ago   /bin/sh -c #(nop) ADD file:7633003155a105941ā€¦   72.8MB
> docker history ubuntu.azurecr.io/ubuntu:focal
IMAGE          CREATED       CREATED BY                                      SIZE      COMMENT
04441f7fff00   13 days ago   /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
<missing>      13 days ago   /bin/sh -c #(nop) ADD file:5dfb5928594745d5dā€¦   72.8MB
<missing>      13 days ago   /bin/sh -c #(nop)  LABEL org.opencontainers.ā€¦   0B
<missing>      13 days ago   /bin/sh -c #(nop)  LABEL org.opencontainers.ā€¦   0B
<missing>      13 days ago   /bin/sh -c #(nop)  ARG LAUNCHPAD_BUILD_ARCH     0B
<missing>      13 days ago   /bin/sh -c #(nop)  ARG RELEASE                  0B

You can see in both images that they use the ADD instruction. For whatever reason, the dockle tool doesn't produce a violation for the image from Docker Hub even though its first two layers are structured the same as the image from ubuntu.azurecr.io.

Looking at the dockle code, I see this relevant section:

https://github.com/goodwithtech/dockle/blob/09d597ce1e5d92e9050ea4867ea07f78ef4ad33b/pkg/assessor/manifest/manifest.go#L173-L179

That code is checking for the violation of CIS-DI-0009. You can see that they check the layer index and skip the check if it's the first layer. That makes sense since nearly all images use the ADD instruction to inject the initial file system. But I'm confused on how that works since it's checking for index 0 and the output of the history commands above show that index 0 is the CMD instruction. So it's not clear to me why the image from Docker Hub also doesn't violate this check.

Regardless, the maintainers of the dockle tool should investigate this because looking at the image history shows there's really no consequential difference between the images hosted between Docker Hub and ubuntu.azurecr.io. So please log an issue with dockle.

ThorstenHans commented 1 year ago

Thanks @mthalman šŸ™šŸ¼ for looking into this. I've created the corresponding issue in the dockle repository.

mthalman commented 1 year ago

After discussing this with others I realized that I interpreted the history in the incorrect order. The Docker Hub image has the ADD instruction as the first instruction which gets skipped according to dockle's logic. But for the image in the Ubuntu ACR, the first instruction is an ARG. The ADD instruction doesn't occur until several other instructions in the history. So that's not causing the check to be skipped in dockle's logic. This leads to the violation.

This is the Dockerfile used by the image from the Ubuntu ACR (from https://git.launchpad.net/cloud-images/+oci/ubuntu-base/tree/Dockerfile?h=focal-20.04):

FROM scratch
ARG RELEASE
ARG LAUNCHPAD_BUILD_ARCH
LABEL org.opencontainers.image.ref.name="ubuntu"
LABEL org.opencontainers.image.version=$RELEASE
ADD ubuntu-*-oci-$LAUNCHPAD_BUILD_ARCH-root.tar.gz /
CMD ["/bin/bash"]

As you can see, the ARG instructions are listed first and the ADD instruction depends on one of them. So it's not possible for the ADD instruction to be listed first in the history. So dockle needs to account for this scenario by allowing for empty layers to be listed before the first ADD instruction.

mthalman commented 1 year ago

Closing this since this is something that dockle needs to account for, based on what I mentioned above.