Il report arriva in un PDF di decine di pagine: un vulnerability assessment commissionato per un audit, la scansione trimestrale richiesta dal fornitore dei pagamenti, il controllo periodico di un cliente importante. In cima, segnato in rosso, c’è PHP: versione non supportata, seguita da un elenco di CVE con punteggi critici. La tentazione è di reagire in uno dei due modi sbagliati, cioè ignorare tutto come falso positivo o considerare tutto come un’emergenza.
In questo articolo spieghiamo come lo scanner arriva alle sue conclusioni, come leggere ogni riga del report, come distinguere le segnalazioni vere da quelle dedotte solo dal numero di versione e come rispondere con prove che reggano in un audit. Con un PHP fuori supporto la risposta onesta contiene sempre due parti: cosa è già corretto e quando si migra.
Cosa vede davvero lo scanner
Uno scanner di vulnerabilità non esegue exploit su ogni CVE che elenca. Nella maggior parte dei casi identifica il software e la sua versione, poi la confronta con un database di vulnerabilità note. Per PHP le fonti più comuni sono due:
- dall’esterno, l’intestazione HTTP
X-Powered-By, che PHP aggiunge alle risposte quando la direttivaexpose_phpè attiva e che contiene il numero di versione, oppure il banner del server web; - dall’interno, nelle scansioni autenticate, l’elenco dei pacchetti installati letto dal gestore dei pacchetti del sistema.
In entrambi i casi lo scanner vede un numero, per esempio 5.4.16 o 7.4.33, e da quel numero deduce le CVE. Red Hat lo spiega nella sua pagina sul backporting: alcuni strumenti di scansione decidono sulle vulnerabilità solo in base al numero di versione, e producono falsi positivi perché non tengono conto delle correzioni portate dalle distribuzioni sulle versioni vecchie. Le domande frequenti sulla sicurezza di Debian rispondono alla stessa obiezione: il numero di versione resta quello della release stabile anche quando le falle sono corrette.
Le scansioni autenticate sono in genere più precise. Alcuni strumenti confrontano la versione completa del pacchetto, compresa la release, con i dati di sicurezza pubblicati dalle distribuzioni, come i feed OVAL di Red Hat, e riconoscono così i backport ufficiali. Un pacchetto ricostruito da un fornitore diverso dalla distribuzione non compare in quei dati, quindi anche una scansione autenticata può continuare a segnalare come aperte vulnerabilità già corrette. Per questo, quando possibile, conviene chiedere che il report indichi per ogni riga il metodo con cui la vulnerabilità è stata rilevata.
I tre tipi di segnalazione
Le righe su PHP di un report ricadono quasi sempre in tre categorie, che vanno trattate in modo diverso.
Versione non supportata
Lo scanner segnala che il ramo di PHP ha superato la fine del supporto indicata su php.net. Questa segnalazione è vera per definizione: un ramo in End of Life resta tale anche se il pacchetto contiene correzioni. Va gestita con un piano.
CVE dedotte dalla versione
È l’elenco più lungo e quello che richiede più lavoro. Ogni CVE va verificata su tre piani: se il pacchetto installato la corregge già, se il codice vulnerabile esiste nel ramo in uso e se è raggiungibile con la SAPI, le estensioni e la configurazione del server. Alcune righe risulteranno corrette, altre non applicabili, altre vulnerabilità reali.
Configurazione
Segnalazioni come la versione esposta nelle intestazioni, una pagina phpinfo() raggiungibile o un file di test dimenticato. Sono semplici da correggere e vanno corrette, ricordando che nascondere la versione toglie un’informazione all’attaccante e lascia invariata la vulnerabilità.
Come leggere una riga del report
Per ogni segnalazione su PHP conviene annotare quattro informazioni: l’identificativo della CVE, il metodo di rilevamento, la versione rilevata e il punteggio. Il metodo di rilevamento è il più importante, perché dice se lo scanner ha verificato qualcosa o ha solo letto un numero. Molti report lo indicano esplicitamente, con formule come «rilevato dal banner» o «basato sulla versione».
Anche il punteggio va letto con attenzione. Lo stesso CVSS può variare secondo chi lo calcola: per la CVE-2019-11043 NVD indica 9.8, il progetto PHP 8.7 e Red Hat 8.1, perché valutano in modo diverso la complessità dell’attacco. Il punteggio descrive la vulnerabilità in astratto; il rischio reale dipende dalla tua configurazione. Una CVE critica di PHP-FPM su un server che usa mod_php non comporta alcun rischio, una CVE media in un’estensione caricata e raggiungibile da un modulo pubblico può essere più urgente.
Un altro elemento utile per ordinare le priorità è sapere se una CVE è sfruttata attivamente. L’agenzia statunitense CISA pubblica un catalogo delle vulnerabilità note e sfruttate, in cui compaiono anche alcune falle di PHP, tra cui la CVE-2019-11043, inserita nel marzo 2022. Una riga del report che corrisponde a una voce di quel catalogo, su un server dove le condizioni di sfruttamento sono presenti, va in cima alla lista.
Rispondere, segnalazione per segnalazione
La risposta a un report è un documento che chi ha commissionato la scansione, o un auditor, deve poter verificare. Per ogni riga serve un esito e una prova. Lo schema qui sotto riassume il percorso.
Le prove più solide si raccolgono direttamente dal server. Il changelog del pacchetto è il documento che lega una CVE alla versione installata:
# Versione completa, con la release della distribuzione o del fornitore
rpm -q php-common php-fpm # RHEL, Rocky, Alma, SUSE
dpkg-query -W -f='${Package} ${Version}\n' 'php*-common' # Debian e Ubuntu
# La CVE segnalata compare nel changelog del pacchetto installato?
rpm -q --changelog php-common | grep -i 'CVE-2019-11043'
zcat /usr/share/doc/php*-common/changelog.Debian.gz | grep -i 'CVE-2019-11043'
# Cosa vede lo scanner dall'esterno
curl -sI https://www.example.com/ | grep -iE 'x-powered-by|^server'
Per le CVE non applicabili la prova è un’analisi breve ma precisa: la SAPI in uso, l’elenco delle estensioni caricate, la parte di configurazione rilevante e il motivo per cui la condizione non si verifica. Per le vulnerabilità reali la risposta indica la mitigazione applicata, la correzione prevista e la data. I database delle distribuzioni, come quello delle CVE di Red Hat o il security tracker di Debian, aiutano a documentare quali pacchetti sono corretti e con quale versione.
Il caso dei pacchetti con backport
Se il server usa un PHP corretto con un backport delle patch, il report elencherà come aperte CVE che sono già chiuse, perché il numero di versione non cambia. È lo stesso meccanismo che Red Hat descrive per i suoi pacchetti, e la risposta è la stessa: il changelog del pacchetto riporta ogni CVE corretta, e si allega al report.
Resta vera la segnalazione sulla versione non supportata, e va detto chiaramente. Il backport chiude le vulnerabilità note e non rende il ramo supportato. In un audit la combinazione che regge è questa: elenco delle CVE corrette con le prove, analisi di quelle non applicabili, piano di migrazione con una data.
Cosa non fare
- Nascondere la versione per far sparire le righe dal report. Con
expose_phpdisattivato una scansione esterna può non riconoscere più la versione, ma le vulnerabilità restano dove sono. Il report migliora e il server resta esposto. - Dichiarare falsi positivi senza prove. Un auditor chiederà il changelog o l’analisi, e una risposta generica fa perdere credibilità anche alle segnalazioni contestate a ragione.
- Trattare tutto come critico. Correggere in fretta righe che non si applicano toglie tempo a quelle che contano.
- Rispondere una volta sola. La scansione si ripete, e su un ramo fuori supporto ogni nuova CVE comparirà nel report successivo.
Dal report al piano
Un report ben letto è un buon punto di partenza per decidere. Le righe vere dicono cosa correggere subito, quelle sulla versione non supportata dicono che serve una data di migrazione, e la risposta documentata diventa la base per la scansione successiva e per gli audit di conformità. Abbiamo approfondito il rapporto tra vulnerabilità di PHP e standard come PCI DSS e ISO 27001 nell’articolo dedicato alle vulnerabilità di PHP negli audit.
Se hai ricevuto un report su un PHP fuori supporto e vuoi separare le segnalazioni vere da quelle dedotte dalla versione, possiamo analizzarlo insieme partendo dai pacchetti installati: scrivici allegando le righe che riguardano PHP.
In sintesi
Quando uno scanner segnala PHP obsoleto, quasi sempre ha letto un numero di versione dall’intestazione X-Powered-By o dai pacchetti installati e ne ha dedotto un elenco di CVE. Le segnalazioni vanno divise in tre gruppi: la versione non supportata, che è vera e richiede un piano di migrazione; le CVE dedotte dalla versione, da verificare una per una sul changelog del pacchetto e sulla configurazione reale; i problemi di configurazione, semplici da correggere. Ogni CVE finisce in un esito, corretta, non applicabile o vulnerabilità reale, sempre accompagnato da una prova. Nascondere la versione migliora il report e lascia il server com’è. Con un backport in uso, il changelog documenta le correzioni, mentre la data di migrazione risponde alla segnalazione sul ramo fuori supporto.