
Gehärtetes dasel v3.3.1 Paket und Image erstellt mit Melange und apko. Patchen von CVE-2026-33320.
# dasel v3.3.1 gehärteter Container
Dies ist ein Melange-Paket und ein apko-Container-Image für [dasel v3.3.1](https://github.com/TomWright/dasel/releases/tag/v3.3.1) mit einem Build-Zeit-Patch für [CVE-2026-33320](https://github.com/TomWright/dasel/security/advisories/GHSA-4fcp-jxh7-23x8) (unbegrenzte YAML-Alias-Expansion). Das Image wird vollständig aus einem lokal erstellten APK erstellt – es wird kein vorab erstelltes Upstream-Image verwendet.
## Voraussetzungen
| Werkzeug | Getestete Version | Zweck |
| -------- | ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
| Docker | 29.3.1 | Container-Laufzeit, führt melange/apko via `compose.yaml` aus |
| melange | 0.50.5 (Docker-Image `cgr.dev/chainguard/melange@sha256:b6f11bb45a6090c182986028fd2249fb1a18dcb6e173c4ce001dd3fb4cb1dd71`) | APK-Paket-Builder |
| apko | 1.2.10 (Docker-Image `cgr.dev/chainguard/apko@sha256:20dfc1f5e3461b5eaf3279f762cd4bf86c7f3635d2a9642f905cf583525f9ee6`) | OCI-Image-Builder |
- Architektur: **x86_64** nur
- Internetzugang für den Erstbau erforderlich (holt Quell-Tarball, Go-Module, Wolfi-Pakete)
### Windows-Anforderungen
Alle Build- und Ladebefehle funktionieren von jedem Terminal (PowerShell, CMD oder bash). Ein Schritt erfordert noch eine Unix-Shell:
- `bash tests/test.sh` – das Testskript verwendet bash und coreutils (`timeout`, `grep`, `sed`)
Installieren Sie **Git Bash** (wird mit [Git für Windows](https://git-scm.com/download/win) ausgeliefert), bevor Sie die Image-Tests ausführen.
## Projektstruktur
```
.
├── .github/
├── melange/
│ ├── dasel.yaml
│ └── CVE-2026-33320.patch
├── apko/
│ └── dasel.yaml
├── tests/
│ └── test.sh
├── Makefile
├── compose.yaml
├── keys/ # Generiert, gitignoriert
│ ├── melange.rsa
│ └── melange.rsa.pub
├── sbom/ # Generiert, gitignoriert
│ ├── sbom-x86_64.spdx.json
│ └── sbom-index.spdx.json
├── packages/ # Generiert, gitignoriert
│ └── x86_64/
│ ├── dasel-3.3.1-r0.apk
│ └── APKINDEX.tar.gz
└── README.md
```
## Build
### Mit Make
```bash
make build # keygen (falls nötig) + Paket + Image
make test # Paket-Tests + Image-Tests
make all # build + test
make clean # Entfernt alle generierten Artefakte
make help # Listet alle Ziele und Variablen
```
### Manuelle Befehle
```bash
# 1. Signierschlüssel generieren (einmalig)
docker compose run --rm melange keygen keys/melange.rsa
# 2. APK-Paket bauen (holt Quelle, wendet CVE-Patch an, kompiliert)
docker compose run --rm melange build melange/dasel.yaml --arch x86_64 --signing-key keys/melange.rsa
# 3. OCI-Image bauen (verbraucht lokales APK)
docker compose run --rm apko build apko/dasel.yaml dasel:3.3.1 dasel.tar --arch x86_64 --sbom-path sbom/
```
Schritt 2 erzeugt und signiert automatisch `packages/x86_64/APKINDEX.tar.gz`.
## Ausführen
Nach dem Laden des Images, führen Sie dasel aus:
```bash
docker load --input dasel.tar
# Beispiel: Abfrage einer JSON-Datei
echo '{"name": "dasel"}' | docker run --rm \
--read-only \
--cap-drop=ALL \
--security-opt=no-new-privileges \
-i dasel:3.3.1-amd64 \
-i json 'name'
```
Diese Flags setzen die Laufzeitschicht der abwehr-in-der-Tiefe-Strategie durch, die in [Image-Härtung](#image-härtung) beschrieben wird: ein unveränderliches Root-Dateisystem, null Linux-Fähigkeiten und keine Privilegieneskalationspfade.
## Test
### Mit Make
```bash
make test # alle Tests (Paket + Image)
make package-test # nur Melange-Paket-Tests
make image-test # nur Image-Tests (erfordert bash)
```
### Manuelle Befehle
```bash
# Paket-Tests
docker compose run --rm melange test melange/dasel.yaml --arch x86_64
# Image-Tests (erfordert Git Bash unter Windows)
docker load --input dasel.tar
bash tests/test.sh
```
Das Testskript überprüft:
- Image lädt und `dasel version` meldet `v3.3.1`
- JSON-Schlüsselextraktion (`-i json 'test'`)
- JSON-zu-YAML-Konvertierung (`-i json -o yaml --root`)
- CVE-Patch: bösartiges Billion-Laughs-YAML löst `"yaml expansion budget exceeded"` aus statt hängen zu bleiben
## CVE-2026-33320-Fix
Die Schwachstelle ermöglicht unbegrenzten CPU-/Speicherverbrauch über exponentiell verschachtelte YAML-Aliase (Billion-Laughs-Angriff). Der Patch unter `melange/CVE-2026-33320.patch` fügt zwei Sicherungen in das YAML-Lese-Modul von dasel ein: eine Expansionstiefenbegrenzung (32), die rekursive Alias-Verschachtelung begrenzt, und ein Expansionsbudget (1000), das die Gesamtzahl der Alias-Dereferenzierungen pro Dokument begrenzt. Wenn eine dieser Grenzen erreicht wird, gibt die Decodierung sofort einen Fehler zurück.
## Sicherheit, Reproduzierbarkeit & Minimalität
- **Sicherheit**: CVE-2026-33320 zur Bauzeit gepatcht. Alle Pakete sind signiert. Image enthält nur 3 APK-Pakete (wolfi-baselayout, ca-certificates-bundle, dasel)
- **Reproduzierbarkeit**: Deklaratives YAML für sowohl Paket als auch Image. Quell-Tarball per SHA256 festgelegt. Alle Tool-Versionen dokumentiert. Go-Binary mit `-trimpath` gebaut, um lokale Build-Pfade zu entfernen
- **Minimalität**: Keine Shell, kein Paketmanager im endgültigen Image – nur das dasel-Binary, CA-Zertifikate und Baselayout
### Image-Härtung
Das Image wendet über die Minimalverpackung hinaus eine abwehr-in-der-Tiefe an:
| Schicht | Maßnahme | Wirkung |
| ------- | ----------------------------------- | ---------------------------------------------------- |
| Build | Nicht-Root-Benutzer (UID 65532) | Container-Prozess läuft nie als Root |
| Build | `-s -w` ldflags + auto `-trimpath` | Gestripptes Binary, kein lokaler Pfadverlust |
| Build | Nur 3 Pakete | Minimale Angriffsfläche, keine Shell oder Paketmanager|
| Runtime | `--read-only` | Unveränderliches Root-Dateisystem |
| Runtime | `--cap-drop=ALL` | Null Linux-Fähigkeiten |
| Runtime | `--no-new-privileges` | Verhindert Privilegieneskalation via setuid/setgid |
## Schwachstellenscan
Das erstellte Image (`dasel.tar`) wurde mit branchenüblichen Tools gescannt, um das Sicherheitsniveau über den CVE-Patch hinaus zu validieren.
### Syft (SBOM-Generierung)
Syft extrahierte **36 Pakete** aus dem Image, indem es die Modul-Metadaten des Go-Binarys untersuchte:
- **3 APK-Pakete**: `wolfi-baselayout` 20230201-r29, `ca-certificates-bundle` 20260413-r0, `dasel` 3.3.1-r0
- **32 Go-Module**: darunter `go.yaml.in/yaml/v4`, `github.com/hashicorp/hcl/v2`, `github.com/pelletier/go-toml/v2`, `github.com/goccy/go-json`, `github.com/charmbracelet/bubbletea`, `golang.org/x/sys`, `golang.org/x/text`, `stdlib` go1.25.9 und 25 weitere
- **19 inventarisierte Dateien**: `/usr/bin/dasel`, `/etc/ssl/certs/ca-certificates.crt`, APK-DB, SBOMs pro Paket und Baselayout-Konfigurationsdateien
### Grype (Schwachstellenscanner)
Das erzeugte SBOM wurde mit Grype untersucht, wobei keine weiteren Schwachstellen in den 32 Go-Modulen oder den 3 APK-Paketen gefunden wurden.
## Einreichung
### Annahmen
- **Nur x86_64** – Einfach-Architektur-Build. Multi-Arch würde zusätzliche `--arch`-Flags erfordern
- **Wegwerf-Signierschlüssel** – lokal erzeugt und gitignoriert. In einer Produktionsumgebung sollten private Signierschlüssel in einem Secrets-Manager gespeichert werden, nicht im lokalen Dateisystem. Selbst wenn gitignorierte Dateien durch Backup-Tools, Container-Volume-Mounts oder ein kompromittiertes Arbeitsgerät offengelegt werden können.
- **Wolfi-OS-Abhängigkeit** – Der Bau und das endgültige Image hängen von Wolfi-Paketen ab (`busybox`, `go`, `ca-certificates-bundle`). Wenn in einem dieser Upstream-Pakete eine Schwachstelle entdeckt wird, wäre dieses Image ebenfalls betroffen. In der Produktion wäre es notwendig, Wolfi-Pakete auf dem neuesten Stand zu halten oder ihre Sicherheitshinweise zu abonnieren.
- **Docker Compose-Wrapper** – melange und apko laufen als Docker-Container via `compose.yaml`. Dies wurde auf Kali 2025.3 entwickelt und auf Windows 10 mit Docker Desktop 29.3.1 verifiziert
- **Testskript benötigt bash** – `tests/test.sh` verwendet `timeout` (coreutils) und die Docker-CLI. Alle anderen Befehle sind reines `docker` und funktionieren in PowerShell oder CMD. Unter Windows führen Sie das Testskript in Git Bash aus (siehe [Windows-Anforderungen](#windows-anforderungen))
### SBOM-Abdeckungslücke
apko erzeugt automatisch SPDX-SBOMs zur Bauzeit im `sbom/`-Verzeichnis (`sbom/sbom-x86_64.spdx.json`, `sbom/sbom-index.spdx.json`). Diese verfolgen die 3 installierten APK-Pakete mit Versionen, CPEs, Quellherkunft und Melange-Build-Definitionsreferenzen. Sie enthalten jedoch **nicht** die Go-Modul-Abhängigkeiten, die in das `dasel`-Binary eincompiliert sind. Ich entschied mich, diese zu scannen und verwendete Syft, um diese Lücke zu schließen, indem alle 32 Go-Module aus den eingebetteten Metadaten des Binarys extrahiert wurden.
Für eine Produktionsumgebung sollte eine Automatisierung der SBOM-Extraktion eingerichtet werden, die regelmäßig abfragt. Dann könnte man die SBOM-Ergebnisse mit etwas wie [https://github.com/nedlir/CVEnotifier](https://github.com/nedlir/CVEnotifier) verbinden, das ich in Golang geschrieben habe, um neuartige Schwachstellen in der Lieferkette zu finden.
### Ausgeführte Befehle und Ergebnisse
| Befehl | Ergebnis |
| ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ |
| `docker compose run --rm melange keygen keys/melange.rsa` | Bestanden |
| `docker compose run --rm melange build melange/dasel.yaml --arch x86_64 --signing-key keys/melange.rsa` | Bestanden – Patch angewendet (7/7 Hunks), APK erstellt |
| `docker compose run --rm melange test melange/dasel.yaml --arch x86_64` | Bestanden – Version, JSON-Schlüsselextraktion, JSON-Array-Zugriff |
| `docker compose run --rm apko build apko/dasel.yaml dasel:3.3.1 dasel.tar --arch x86_64 --sbom-path sbom/` | Bestanden – 3 Pakete installiert, OCI-Tarball erstellt |
| `docker load --input dasel.tar` | Bestanden – `dasel:3.3.1-amd64` geladen |
| `bash tests/test.sh` | Bestanden – alle Tests (Version, Schlüsselextraktion, Formatkonvertierung, YAML-Aliase, CVE-Patch) |
| `docker run --rm -v ... anchore/grype:latest /work/dasel.tar` | Bestanden – 1 Fund (erwarteter False-Positive für den gepatchen CVE) |
| `docker run --rm -v ... anchore/syft:latest /work/dasel.tar` | Bestanden – 36 Pakete katalogisiert (3 APK + 32 Go + 1 stdlib) |
### Zukünftige Verbesserungen
- **Multi-Arch-Builds** – Unterstützung mehrerer Architekturen für den Bau dieses Containers.
- **CI/CD-Pipeline** – Automatisierung von Build + Test in GitHub-Aktionen mit melange/apko-Container-Aktionen
- **Go-Ebene-SBOM in melange** – Ausführen von `syft` während der Melange-Build-Pipeline und Einbettung des Go-Modul-SBOM neben dem APK