In breve: un'immagine Docker contiene PHP nello stato del momento della build e invecchia anche senza modifiche al codice. Chi ricostruisce automaticamente le immagini, a intervalli pianificati e in caso di segnalazioni di sicurezza, verifica la versione di PHP nella pipeline e la pubblica tramite digest, porta in produzione in modo pianificabile patch come quella contro PHP2Shell. Una build verde da sola non è una prova; conta la versione nel container in esecuzione.
Perché le immagini invecchiano senza modifiche al codice
In molti team la pipeline di build parte solo quando qualcuno modifica il codice. Per l'applicazione è logico. Per la sicurezza è un problema, perché il PHP nell'immagine proviene dall'immagine di base con il tag dell'ultima build.
PHP2Shell lo ha reso visibile. Le versioni corrette 8.5.12, 8.4.27, 8.3.36 e 8.2.35 sono uscite il 21 ottobre 2026. Un progetto su cui in quei giorni nessuno ha lavorato non ha ricevuto una nuova build ed è rimasto con il vecchio PHP, anche se l'immagine di base era da tempo aggiornata. La via manuale per uscire da questa situazione la descrive Aggiornare PHP nei container Docker. Questo articolo mostra come automatizzarla.
Ricostruire automaticamente le immagini Docker: tre inneschi
Un processo robusto combina più inneschi, perché nessuno debba reggere da solo.
| Innesco | Attuazione | Da tenere presente |
|---|---|---|
| Pianificazione | workflow pianificato, ad es. settimanale | recupera le patch anche senza modifiche al codice |
| Nuova immagine di base | strumento che monitora le immagini di base e propone modifiche | agisce soprattutto con tag di versione fissi |
| Segnalazione di sicurezza | avvio manuale della pipeline da parte del team operativo | richiede un responsabile chiaro |
Con GitHub Actions la pianificazione è affidata all'evento schedule. Secondo la documentazione di GitHub usa la sintassi cron a cinque campi, gira in UTC e solo sul branch predefinito. Le esecuzioni pianificate possono partire in ritardo con carico elevato e, nei repository pubblici, GitHub le disattiva dopo 60 giorni senza attività. Proprio quest'ultimo punto colpisce i progetti tranquilli, cioè quelli che hanno più urgente bisogno della ricostruzione automatica.
Per il secondo innesco, secondo la documentazione di GitHub Dependabot supporta l'ecosistema docker e propone come pull request i nuovi stati delle immagini di base. Vanno conosciute due limitazioni. Primo, qualcuno deve verificare e unire la pull request, altrimenti resta lì. Secondo, con un tag di ramo come php:8.3-fpm nel Dockerfile non cambia nulla quando l'immagine di base viene ricostruita. Uno strumento che propone modifiche al testo non ha allora nulla da proporre. Proprio per questo serve in aggiunta la ricostruzione pianificata.
Il terzo innesco sembra banale, ma in pratica spesso fallisce sulla domanda di chi lo attivi. Stabilisca chi segue le segnalazioni di sicurezza su PHP e chi può avviare la pipeline, anche nel fine settimana. Con PHP2Shell tra il preavviso e la patch è passato solo un giorno.
Una pipeline che intercetta il PHP obsoleto
L'esempio seguente per GitHub Actions ricostruisce l'immagine ogni settimana e a richiesta, verifica la versione di PHP e interrompe se è inferiore allo stato corretto. Registry, nomi e versione minima li adatti Lei.
name: php-image-rebuild
on:
schedule:
- cron: "0 3 * * 1" # ogni lunedì alle 03:00 UTC
workflow_dispatch: {} # avvio manuale in caso di segnalazioni di sicurezza
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Image ohne Cache und mit frischem Basis-Image bauen
run: docker build --pull --no-cache -t app:${{ github.run_id }} .
- name: PHP-Version prüfen (Mindeststand des Zweigs 8.3)
run: |
docker run --rm app:${{ github.run_id }} php -v
docker run --rm app:${{ github.run_id }} \
php -r 'exit(version_compare(PHP_VERSION, "8.3.36", ">=") ? 0 : 1);'
Il controllo della versione funziona con le immagini PHP ufficiali, il cui numero di versione indica lo stato effettivo. Se la Sua immagine usa pacchetti PHP di una distribuzione, il numero dopo un backport resta spesso lo stesso. In tal caso verifichi, invece del numero, il changelog del pacchetto per i numeri CVE, come descritto nell'articolo Dimostrare i numeri CVE nel changelog del pacchetto.
Dopo la verifica seguono in pratica altri tre passaggi: scansionare l'immagine alla ricerca di vulnerabilità note, inviarla al registry con data e digest e passare il digest alla distribuzione. Quali tag e varianti si prestino come base lo spiega Immagini Docker PHP ufficiali.
Dalla build al container in esecuzione
L'errore di ragionamento più frequente: la pipeline è verde, quindi è tutto aggiornato. In realtà la nuova immagine si trova solo nel registry. La patch diventa efficace solo quando ogni container è stato ricreato dalla nuova immagine.
- Pubblicare tramite digest: la distribuzione fa riferimento al digest della nuova immagine, non a un tag mobile.
- Prima staging, poi produzione: test automatici su una copia intercettano le rotture dovute a nuove immagini di base.
- Verificare in esercizio: dopo il rollout eseguire
php -vnel container in esecuzione e confrontare il digest con la build. - Limitare il ritorno indietro: la vecchia immagine resta disponibile per un breve ritorno, ma contiene il PHP vulnerabile.
In Kubernetes valgono regole proprie, ad esempio sulla pull policy; si trovano in Aggiornare PHP in Kubernetes.
Lacune tipiche nella catena
- Cache di build sul runner: senza
--pulle--no-cacheviene riutilizzata la vecchia immagine di base. - Mirror del registry: una cache interna distribuisce ancora il vecchio stato dell'immagine di base.
- Build multistadio: conta la versione di PHP dell'ultimo stadio, ma spesso si verifica solo il primo.
- Immagini secondarie: queue worker, container cron e strumenti interni hanno pipeline proprie o nessuna.
- Digest inseriti in modo fisso: un digest dell'immagine di base una volta fissato non viene mai aggiornato se nessuno strumento lo monitora.
Una ricostruzione sostituisce PHP, non i dati. Il codice dannoso entrato prima della patch in volumi, cartelle di upload o database resta e va verificato separatamente.
Chi reagisce se la ricostruzione fallisce?
Una ricostruzione automatica vale quanto la reazione al suo fallimento. Se il controllo della versione scatta o la build si interrompe a causa di un'immagine di base modificata, qualcuno deve accorgersene. In molti team tali segnalazioni finiscono in una casella che nessuno legge o in un canale in cui le build rosse sono da tempo la norma.
Si è rivelata valida una regola chiara: una ricostruzione di sicurezza fallita è un ticket con un responsabile e una scadenza, non un'indicazione tra tante. Annoti inoltre per ogni immagine pubblicata data, digest e versione di PHP verificata. Questo elenco alla segnalazione successiva risponde in pochi minuti a quali applicazioni siano interessate e serve da prova nei confronti di revisori o assicuratori. Come ne nasca un processo permanente lo descrive Gestione delle patch come processo, non come pronto intervento.
Come aiuta concretamente PHP SOS?
- Verificare le pipeline: esaminiamo le Sue catene di build e rollout e mostriamo dove una patch può restare bloccata.
- Automatizzare la ricostruzione: configuriamo build pianificate, controllo della versione e rollout tramite digest.
- Rilevare tutte le immagini: associamo a ogni container in esecuzione la sua pipeline, comprese le immagini secondarie e quelle vecchie.
- Assistere nel tempo: nel contratto di manutenzione della sicurezza seguiamo le segnalazioni di sicurezza e avviamo le ricostruzioni.
Domande frequenti
Ogni quanto va ricostruita un'immagine PHP?
Non esiste un numero fisso. Si è rivelata valida una build pianificata regolare, ad esempio settimanale, più una build immediata in caso di segnalazioni di sicurezza. Decisivo è che una nuova patch non debba attendere la modifica successiva del codice.
Una build riuscita basta come prova?
No. Una build dimostra solo che esiste una nuova immagine. Solo quando i container in esecuzione sono stati ricreati da questa immagine e php -v vi mostra la versione corretta, la patch è efficace.
Perché dopo la ricostruzione compare comunque la vecchia versione di PHP?
Cause frequenti sono una cache di build che riutilizza la vecchia immagine di base, un mirror del registry con lo stato vecchio o una seconda riga FROM in una build multistadio. Costruisca con --pull e --no-cache e verifichi ogni stadio.
Dependabot può aggiornare le immagini di base?
Secondo la documentazione di GitHub, Dependabot supporta l'ecosistema Docker per gli aggiornamenti di versione e di sicurezza. Propone le modifiche alle immagini di base come pull request. Non sostituisce la ricostruzione con tag invariato.