Validatore Compose
Trova rischi nei container- !privileged: true concede un accesso quasi a livello host.
- !Una password appare in chiaro. Usare i secrets o un archivio esterno.
- △Fissare l'immagine a una versione immutabile o a un digest invece di :latest.
- △La porta pubblicata risulta esposta su tutte le interfacce; se possibile collegarla a 127.0.0.1.
- △Valutare read_only: true quando il filesystem root non deve essere scrivibile.
Introduzione
Il validatore Compose esamina una compose.yaml incollata per cinque rischi di sicurezza dei container che compaiono negli incidenti di produzione: modalità privileged, segreti in chiaro, immagini non pinnate, porte collegate a tutte le interfacce e filesystem root scrivibile.
I file Compose si leggono come configurazione, ma diventano il confine di sicurezza dei tuoi container. Piccoli errori qui mappano direttamente su rischi a livello host.
Obiettivo
- Segnalare privileged: true, che è quasi accesso a livello host.
- Rilevare password e credenziali scritte inline nel file.
- Avvisare sui tag immagine :latest, non riproducibili.
- Avvisare sulle porte pubblicate esposte su tutte le interfacce e sull'assenza di read_only: true.
Input
- Un incolla di compose.yaml (o della sezione services).
- La struttura YAML non viene analizzata a fondo; i controlli si basano su pattern nel testo visibile.
Come funziona
Il file viene scansionato con cinque controlli per pattern. privileged: true è un risultato alto perché concede quasi tutte le capability e disattiva la maggior parte dell'isolamento.
Qualsiasi riga con un'assegnazione di password (password: o PASSWORD=) è un risultato alto: i segreti appartengono ai Docker secrets o a un archivio esterno.
image: ...:latest produce un avviso perché lo stesso file può tirare contenuti diversi nel tempo; un digest immutabile o una versione pinnata è riproducibile.
Una porta pubblicata (host:container) non collegata a 127.0.0.1 è un avviso, così come un servizio senza read_only: true sul suo filesystem root.
Esempio testabile
Prova — l'analisi gira localmente nel tuo browser.
Esempio
services:
api:
image: example/api:latest
ports:
- "8080:8080"
environment:
- DB_PASSWORD=change-me
privileged: trueOutput atteso
Alto: privileged: true concede un accesso quasi a livello host. Alto: Una password appare in chiaro. Usare i secrets o un archivio esterno. Avviso: Fissare l'immagine a una versione immutabile o a un digest invece di :latest. Avviso: La porta pubblicata risulta esposta su tutte le interfacce. Avviso: Valutare read_only: true quando il filesystem root non deve essere scrivibile.
Leggere l'output
- Rimuovi la modalità privileged quando possibile; la maggior parte dei carichi ha bisogno solo di capability specifiche.
- Sposta i segreti inline nei Docker secrets o in un vault esterno e ruota tutto ciò che è stato committato.
- Tag pinnati o digest rendono i deploy riproducibili e i rollback prevedibili.
- Collegare le porte a 127.0.0.1 mantiene i servizi privati a meno che un proxy non li esponga deliberatamente.
Rischi
- privileged: true su un container compromesso equivale di fatto a una compromissione dell'host.
- Le password inline finiscono in immagini, registry e log e non vengono mai ruotate in modo pulito.
- :latest rompe i rollback: l'immagine funzionante di ieri può essere sovrascritta dalla build rotta di oggi.
Limiti
- I controlli per pattern possono perdere rischi espressi con anchor YAML, file di ambiente o istruzioni Dockerfile.
- Non esegue il parser Compose, quindi gli errori di sintassi YAML non vengono segnalati qui.
- Non può rilevare vulnerabilità nelle immagini stesse.
Riferimenti ufficiali
FAQ
Quando è giustificato privileged: true?
Quasi mai in produzione. Alcuni driver legacy e accessi a dispositivi specifici lo richiedono; la via sicura è concedere esattamente le capability necessarie e usare devices: per l'accesso hardware.
Cosa usare al posto delle password inline?
Docker secrets per lo swarm, file di ambiente con permessi ristretti e riferimenti esterni per i segreti vault. Il punto è che i segreti non stiano mai nel file compose o nell'immagine.
read_only: true rompe le app che scrivono file?
Solo se scrivono nel filesystem root. I percorsi scrivibili (upload, cache) possono essere montati come volumi o dichiarati con tmpfs, mantenendo il resto in sola lettura.