1 of 44

Docker:�security disasters

2 of 44

Stefan Walluhn

about me

  • Seit 2000 mit Linux in Kontakt
  • Seit über 10 Jahren Ops / DevOps
  • Seit 2023 in einem Dev-Team
  • about:source GmbH
    • #failed-Channel im Team, um (eigene) Fehler offen zu kommunizieren
    • blame free (eigentlich)
    • Wichtig: lessons learned?
  • devopsdisasters.net

3 of 44

Official base images tagged as latest often include known vulnerabilities, most notably the official node image which has almost 700 known vulnerabilities. Over 30% of survey participants do not review Kubernetes manifests for insecure configurations, and requirements for security-related resource controls in Kubernetes are not widely implemented.

https://snyk.io/series/open-source-security/

4 of 44

5 of 44

Docker

Nochmal ganz von vorn:

warum haben wir Container?

“A container is a standard unit of software that packages up code and all its dependencies so the application runs quickly and reliably from one computing environment to another. A Docker container image is a lightweight, standalone, executable package of software that includes everything needed to run an application: code, runtime, system tools, system libraries and settings.”�

  • Application code
  • Runtime
  • System tools + libraries

6 of 44

System tools & libraries

7 of 44

Docker

ein Beispiel

FROM debian:stable-slim

​

CMD echo “hello world”

8 of 44

Docker

Prozess

+

dessen Laufzeitumgebung

Security Scanner has detected 75 vulnerabilities!

(1 critical; 5 high)

  • Wer von euch nutzt Docker / K8s?
  • Wer rollt neue Container aus, wenn es ein Security-Fix im Base-Image gibt?
  • Wer monitort laufende Docker-Container kontinuierlich auf Vulnerabilities im Base-Image?
  • Wenn ihr Docker-Container nutzt oder anbietet, seid ihr für die Software UND für dessen Laufzeitumgebung verantwortlich!

9 of 44

Docker

Ihr seid für die Software UND

für deren Laufzeitumgebung verantwortlich!

​

10 of 44

Docker

Base Image Security

  • Ubuntu 22.04
    • 39 vulnerabilities
    • 0 critical; 0 high
    • 2 patchable
  • Debian Bookworm (Slim)
    • 75 vulnerabilities
    • 1 critical; 5 high
    • 0 patchable
  • Red Hat UBI8
    • 180 vulnerabilities
    • 0 critical; 0 high
    • 0 patchable
  • Alpine
    • 0 vulnerabilities (aber…)
    • veröffentlicht nur Daten zu bereits gefixten Lücken

Stand: 05.03.2024

11 of 44

12 of 44

Runtime

13 of 44

Docker

node:latest

  • Official Image
  • Maintained by: �The Node.js Docker Team
  • 352.5MB #offtopic

14 of 44

node:latest

FROM buildpack-deps:bookworm

  • Ist das Base-Image aktuell?
    • 875 vulnerabilities
    • 5 critical; 108 high
    • 39 patchable

15 of 44

node:latest

RUN curl "https://nodejs.org/[...]/node-v$NODE_VERSION-linux-$ARCH.tar.xz" \� && tar -xJf "node-v$NODE_VERSION-linux-$ARCH.tar.xz" -C /usr/local

​

  • curl pre-compiled Binary
    • Wann wurde das gebaut?
    • Wo wurde das gebaut?
    • Wie wurde das gebaut?
    • Mit welchen Compiler-Flags?
    • Was wurde statisch gelinkt?
  • tar nach /usr/local/bin/node
    • damit unmöglich, systematisch auf Vulnerabilities zu monitoren
  • steckt da auch npm drin, oder nur node?

16 of 44

node:latest

RUN curl "https://yarnpkg.com/[...]/yarn-v$YARN_VERSION.tar.gz" \� && mkdir -p /opt \� && tar -xzf yarn-v$YARN_VERSION.tar.gz -C /opt/ \� && ln -s /opt/yarn-v$YARN_VERSION/bin/yarn /usr/local/bin/yarn

​

  • curl pre-compiled Binary
  • tar nach /opt/yarn-v$YARN_VERSION
    • damit unmöglich, systematisch auf Vulnerabilities zu monitoren

17 of 44

node:latest

CMD [ “node” ]

  • …als root im laufenden Container

18 of 44

Docker

node:latest

  • gilt für alle Images, die auf node:latest aufbauen
  • gilt analog auf für PHP-, Ruby-, Python, [...]-Base-Images

19 of 44

20 of 44

Application

21 of 44

Docker

owncloud/server:latest

  • Official Image
  • 381,6 MB #offtopic

22 of 44

owncloud/server:latest

FROM owncloud/base:20.04-amd64�FROM owncloud/php:20.04-amd64�FROM owncloud/ubuntu:amd64�FROM ubuntu:20.04

  • basiert NICHT auf dem offiziellen PHP Base-Image (das ist gut!)
  • Ist das Base-Image aktuell?
    • 105 vulnerabilities
    • 0 critical; 0 high
    • 2 patchable
  • Das Patch-Level des finalen Images hängt von der Build-Zeit ab(!!!)

​

FULL DISCLOSURE / UPDATE:

Analyse von 04/2022

​

Stand 05.03.2024

​

  • 143 vulnerabilities
  • 0 critical; 0 high
  • 2 patchable

23 of 44

owncloud/php:20.04-amd64

RUN apt-get update -y && apt-get install -y apache2 libapache2-mod-php

  • YESS!!! Das finden unsere Vulnerability-Scanner!

RUN pecl install smbclient-stable

  • *argl*, zu früh gefreut! Das finden unsere Vulnerability-Scanner nicht :-(

RUN curl -sS https://getcomposer.org/installer | php

  • heul!
    • curl | php
    • als root!
    • ohne Prüfsummen-Check

24 of 44

owncloud/server:20.04-amd64

ADD owncloud.tar.bz2 /var/www

  • Quelle?
    • Wann, wo, wie…?
    • Welche Version?
    • Reproducable build?

25 of 44

owncloud Startup-Scripte

​

  • /etc/owncloud.d/*.sh
    • Webserver bekommt Schreibrechte auf PHP-Code
      • chown www-data:root
      • chmod +x
    • Owncloud-Apps werden nachgeladen
      • curl ${APP}
    • htaccess wird generiert
      • occ maintenance:update:htaccess
    • Apache-Config wird neu geschrieben
      • gomplate -o /etc/apache2/sites-enabled/default.conf
    • Cron-Jobs /Background-Jobs werden generiert
      • gomplate -o /etc/cron.d/owncloud
    • Cron-Deamon wird gestartet
      • /usr/sbin/cron -l
  • Zustandsänderung zur Laufzeit!
    • Docker-Image zur Build-Zeit != Docker-Container zur Laufzeit
    • Im laufenden Container steckt mehr, als ein Vulnerability-Scanner gesehen hat!

gomplate???

26 of 44

owncloud/ubuntu:amd64

ADD https://github.com/[...]/wait-for-linux-amd64 /usr/bin/wait-for�ADD https://github.com/[...]/gosu-amd64 /usr/bin/su-exec�ADD https://github.com/[...]/gomplate_linux-amd64 /usr/bin/gomplate�

  • Das haben auch unsere Vulnerability-Scanner nicht gesehen.
  • wait-for Prüfsumme wird nicht gecheckt
    • kommt von https://github.com/owncloud-ci/, wird als sicher betrachtet
    • Folge: Jede:r mit Zugriff auf das Github-Repo hat Root-Zugriff im offiziellen OwnCloud-Container!
      • Inkl. Github selbst

27 of 44

Docker

owncloud/server:latest

Zur Einordnung

  • Das OwnCloud-Image ist eins der saubersten Docker-Setups, das ich in den letzten Jahren gesehen habe!
  • Da sitzen Menschen, die wissen, wie Docker-Images funktionieren.
  • Die meisten Docker-Images sehen viel gruseliger aus!
  • Trotzdem finden sich diverse Ansätze, die sich für Supply-Chain-Attacken nutzen lassen.
  • Das Patch-Level des Images hängt sowohl von der Build-Zeit, als auch von externen Build-Prozessen ab.
  • Da sich das Image nicht systematisch auf Vulnerabilities monitoren lässt, habt ihr keine Chance sicherzustellen, dass es keine Security-Probleme gibt(!!!)

28 of 44

29 of 44

Application-Stacks

30 of 44

Sentry

official self hosted

​

“Our recommendation is to download the latest release of the self-hosted repository, [...] and then will tell you to run ‘docker-compose up -d’ to start Sentry.”

Oft auch in der Geschmacksrichtung “Nimm das Helm-Chart hier” verfügbar.

31 of 44

Sentry

official self hosted

  • 3rd party Docker Container
    • tianon/exim4:latest
      • Version nicht gepinnt
      • tianon wer?
    • memcached:1.6.21-alpine
      • Image vom 17.10.2023
    • confluentinc/cp-zookeeper:5.5.7
      • Image vom 11.01.2022 (!!!)
      • tons of internal intermediate containers
        • pip, Make, ...
    • confluentinc/cp-kafka:5.5.7
      • same as zookeeper
    • Früher: yandex/clickhouse-server
    • Jetzt: clickhouse-self-hosted-local
      • ARG BASE_IMAGE
        • Wo wird das gesetzt?
      • yandex …
    • [nginx, postgres, redis, ...]
  • Ihr gebt jedem dieser Container Root-Zugang!
  • Ja! Das ist das offizielle Sentry on premise release.

Version 24.2.0; Stand 05.03.2024

32 of 44

Sentry-eigenes Docker-Image

    • FROM python:3.11.6-slim-bullseye
      • Base-Image vom 01.12.2023
      • 142 vulnerabilities; 2 critical; 32 high
    • RUN wget -O - https://github.com/DataDog/uwsgi-dogstatsd/ | tar
      • Prüfsumme wird nicht gecheckt
    • RUN wget -O /usr/local/bin/gosu [...]

33 of 44

34 of 44

K8s

35 of 44

K8s

…ist auch nur ein Haufen Container

  • registry.k8s.io
    • cluster-proportional-autoscaler-amd64
    • coredns/coredns
    • dns/k8s-dns-node-cache
    • etcd
    • kas-network-proxy/proxy-agent
    • kube-apiserver
    • kube-controller-manager
    • kube-proxy
    • metrics-server/metrics-server
    • provider-os/cinder-csi-plugin
    • sig-storage/csi-node-driver-registrar
    • sig-storage/livenessprobe
    • sig-storage/snapshot-controller
    • …
  • Ingress-Controller
  • Prometheus
  • kubermatic/user-ssh-keys-agent
  • Provider-eigene Container

36 of 44

coredns

FROM distroless/static-debian11:nonroot

  • Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
  • Yess!!!

COPY coredns /coredns

  • statically linked go binary
  • Quellen leben im selben Repo
  • Yess!!!

USER nonroot:nonroot

EXPOSE 53 53/udp

ENTRYPOINT ["/coredns"]

  • Yess!!!

37 of 44

K8s

coredns

  • v1.10.1
    • vom 16.03.2023
    • 7 vulnerabilities
      • 0 critical; 3 high
      • alle fixable
  • v1.11.1
    • vom 21.01.2024
    • 6 vulnerabilities
      • 0 critical; 2 high
      • alle fixable
  • Keine Vulnerabilities aus den Base-Images!
  • Die Vulnerabilities betreffen das Go-Binary!
    • HTTP/2 Rapid Reset
    • …

38 of 44

K8s

kube-proxy

  • v1.27.2
    • vom 21.01.2024
    • 52 vulnerabilities
      • 0 critical, 9 high
      • alle fixable
    • Base-Image
      • glibc: buffer overflow in ld.so
      • glibc: potential use-after-free in getaddrinfo()
    • Go Binary
      • DoS from malicious API request
      • runc: file descriptor leak
      • opentelemetry: DoS vulnerability in otelhttp
      • HTTP2 rapid reset
  • v1.29.2
    • vom 14.02.2024
    • 23 vulnerabilities
      • 0 critical, 2 high
    • Base-Image: keine critical; high
    • Go Binary
      • runc: file descriptor leak
      • DoS vulnerability in otelgrpc
      • alle fixable

39 of 44

40 of 44

Docker

und jetzt die schlechte Nachricht

  • Die gezeigten Beispiele sind keine Ausnahmen, sondern die Regel.
  • Ich hatte in den letzten Jahren kaum ein Docker-Setup in der Hand, welches nicht auf den ersten Blick gestunken hat.
  • Das Gezeigte ist Stand der Dinge im Docker-Hype.

41 of 44

Was tun?

42 of 44

Docker

was tun?

  • schaut euch die Dockerfiles an!
  • baut eure Container selber
  • nutzt nur vertrauenswürdige und minimale Base-Images
  • ggf. updatet im ersten Schritt die Base-Images
  • nutzt die Pakete aus dem Paketmanager der Distribution
    • ruby, python, php, ...
    • baut nichts selbst, auch wenn ihr damit ggf. keine bleeding edge Versionen nutzen könnt
    • auch, wenn euch eure Devs dafür hassen!
    • Ziel: Kombination Package-Manager + requirements.txt / Gemfile.lock / package-lock.json beschreibt das System
    • Nutzt SBOMs, das wird langsam brauchbar
  • stellt dieselben Security-Anforderungen wie auf jedem anderen Linux-Server auch
  • scannt eure Images systematisch und kontinuierlich auf Vulnerabilities
  • veröffentlicht kontinuierlich neue Images, auch bei Security-Updates aus den Base-Images
  • K8s… keine Ahnung, ob sich das irgendwie sicher betreiben lässt.

43 of 44

Docker

Ausblicke

  • Base-Images der Distros bekommen inzwischen regelmäßig Updates.
    • teilweise tagesaktuell
  • Problematik der unsicheren Base-Images kommt langsam auf den Radar!
    • Security-Scanner inzwischen in diversen Docker-Repositories integriert
    • Secure Images is a business
  • Security-Scanner werden besser und finden immer mehr.
  • SBOMs im Container-Umfeld werden langsam brauchbar.
  • SBOM-Generatoren und Security-Scanner stehen inzwischen als OpenSource zur Verfügung.
  • Gute Dockerfiles bleiben weiterhin selten
    • make it work statt saubere Setups
    • zu wenig DevOps / Ops-Wissen
  • K8s - na wir werden sehen. Aber das ist eine andere Geschichte und soll ein andermal erzählt werden…

44 of 44

Ende

Danke fürs Zuhören!

www.aboutsource.net

we are hiring!

​

www.devopsdisasters.net

call for disasters!

​

Feedback + Rückfragen

input@devopsdisasters.net