
dasel v3.3.1 impacchettato con Melange e distribuito come immagine apko minimale, corretto per CVE-2026-33320
Questo repository impacchetta la CLI dasel (v3.3.1) come APK con Melange, costruisce un'immagine container minimale con apko e applica una correzione per CVE-2026-33320 pur restando sul codebase v3.3.1 (una patch, non un cambio di versione).
Il risultato è un'immagine di ~4 MB che contiene solo il binario statico dasel — niente shell, niente gestore di pacchetti, niente libc — che gira come utente non-root.
melange/
dasel.yaml # melange recipe: fetch v3.3.1, apply the patch, build the .apk
apko/
dasel.yaml # apko recipe: assemble a minimal image from the local .apk
patches/
cve-2026-33320.patch # the CVE fix (minimal backport of upstream 282943b onto v3.3.1)
NOTES.md # what the CVE is, severity, and how the fix works
tests/
test.sh # runs the built IMAGE and asserts real behavior + the CVE fix
README.md
melange e apko nel PATH.Versioni usate durante lo sviluppo:
| Strumento | Versione |
|---|---|
| melange | 0.50.8 |
| apko | 1.2.14 |
| Docker | 29.5.2 |
Tutti i comandi seguenti vengono eseguiti dalla radice del repository.
melange keygen
Produce melange.rsa (privata) e melange.rsa.pub (pubblica). Entrambe sono in gitignore — le chiavi vengono rigenerate da chiunque riproduca la build e non vengono mai committate.
melange build melange/dasel.yaml \
--source-dir patches \
--signing-key melange.rsa \
--arch x86_64 \
--runner docker
--source-dir patches rende disponibile patches/cve-2026-33320.patch all'interno del sandbox di build, dove lo step patch della ricetta lo applica. Output: packages/x86_64/dasel-3.3.1-r0.apk (firmato) e packages/x86_64/APKINDEX.tar.gz.
melange test installa il .apk appena compilato in un ambiente pulito ed esegue il blocco test: della ricetta. Richiede il repository Wolfi (per busybox) e il nostro repository locale packages/ (per dasel), ciascuno con la propria chiave di firma:
melange test melange/dasel.yaml dasel \
--arch x86_64 --runner docker \
--repository-append https://packages.wolfi.dev/os \
--keyring-append https://packages.wolfi.dev/os/wolfi-signing.rsa.pub \
--repository-append "$(pwd)/packages" \
--keyring-append melange.rsa.pub
Verifica: che dasel version riporti 3.3.1; una query JSON reale; una conversione JSON→YAML; e che una YAML bomb "billion laughs" venga rifiutata dal guard di espansione (CVE-2026-33320 corretto).
apko build apko/dasel.yaml dasel:test dasel.tar --arch x86_64
docker load < dasel.tar
Output: dasel.tar (un'immagine OCI caricabile) più un SBOM (SPDX JSON). apko aggiunge l'architettura al tag, quindi l'immagine caricata è dasel:test-amd64.
Come l'immagine consuma il pacchetto compilato localmente (il vincolo chiave). apko/dasel.yaml elenca ./packages come repository e ./melange.rsa.pub come keyring. apko installa quindi l'esatto APK dasel che melange build ha scritto in packages/x86_64/ — verificato con la nostra chiave di firma — e non un pacchetto upstream precompilato. (Esegui apko build dalla radice del repository così che i percorsi relativi vengano risolti.) Questo è ciò che collega la build del pacchetto alla build dell'immagine.
./tests/test.sh
Esegue l'immagine tramite docker run e verifica (5 controlli): che dasel sia presente e riporti v3.3.1; una query JSON annidata; una conversione JSON→YAML; una query per indice di array; e che la YAML bomb venga rifiutata. Lo script esce con un codice non-zero se un controllo fallisce (così può bloccare la CI). Sovrascrivi il tag con IMAGE=<tag> ./tests/test.sh.
CVE-2026-33320 è una denial-of-service (CWE-674, ricorsione non controllata) nel lettore YAML di dasel: un attacco "billion laughs" tramite espansione di alias YAML senza limiti. dasel ha implementato un proprio UnmarshalYAML e risolveva i nodi alias in modo ricorsivo senza alcun limite, aggirando la protezione integrata della libreria sottostante.
Backportiamo solo la correzione upstream (commit 282943b, inclusa in v3.3.2) sul sorgente v3.3.1 come patches/cve-2026-33320.patch. Limita l'espansione con un limite di profondità (32) e un budget (1000) condiviso, restituendo un errore invece di espandersi senza limiti. Escludiamo deliberatamente le correzioni di bug non correlate incluse anch'esse in v3.3.2, mantenendo la modifica minima e verificabile. Vedi patches/NOTES.md per tutti i dettagli.
git-checkout fissa expected-commit allo SHA del commit v3.3.1, quindi la build fallisce se il tag venisse mai ri-puntato su codice diverso (sicurezza della supply chain).CGO_ENABLED=0 (impostato nell'ambiente di build della ricetta), quindi il binario non ha cgo né dipendenze da librerie condivise — è ciò che consente di distribuire l'immagine senza libc/shell/gestore di pacchetti.packages: di apko include solo dasel; l'immagine installa soltanto il nostro pacchetto compilato localmente (verificato con il nostro melange.rsa.pub).nonroot) per difesa in profondità.x86_64 (l'architettura della macchina di sviluppo).docker come runner di Melange (bubblewrap funzionerebbe anche su Linux nativo)./etc/os-release); nulla nell'immagine ne ha bisogno. È una scelta deliberata di minimalismo, facilmente reversibile aggiungendo wolfi-baselayout.go e busybox rolling di Wolfi invece di snapshot bloccati, quindi presuppone che Wolfi continui a fornire un Go ≥ 1.25 (requisito del go.mod di dasel). Il sorgente di dasel è bloccato per commit; bloccare anche la toolchain di build renderebbe la build completamente ermetica (vedi sotto).go/busybox di Wolfi) e fissare una data di build per una build completamente ermetica e riproducibile bit-per-bit (il sorgente è già bloccato per commit).aarch64) per macchine ARM.melange build + melange test: il pacchetto compila, la patch si applica senza problemi (tutti e 7 gli hunks — 1 in parsing/yaml/yaml.go, 6 in parsing/yaml/yaml_reader.go), tutti i test del pacchetto verdi, incluso il test della bomba CVE.apko build + tests/test.sh: l'immagine compila (~4 MB di contenuto), tutti e 5 i test dell'immagine verdi.