PHP 5.6 nel 2026: perché è ancora ovunque e perché non è innocuo

PHP 5.6 non riceve correzioni ufficiali dal gennaio 2019, eppure gira ancora sotto gestionali ed e-commerce: perché è sopravvissuto così a lungo, cosa comporta restarci, cosa si rompe nel passaggio a PHP 8 e da dove partire.

Copertina con il logo php∞, la categoria PHP End of Life, il titolo PHP 5.6 nel 2026: ancora ovunque e il numero 04

PHP 5.6 ha ricevuto l’ultima correzione ufficiale nel gennaio 2019. Da allora sono usciti undici nuovi rami, dal 7.0 all’8.5, eppure nel 2026 capita ancora spesso di trovarlo in produzione: sotto un gestionale scritto dieci anni fa, sotto un e-commerce che “funziona e non si tocca”, sotto un portale interno che nessuno ricorda più chi abbia sviluppato. Quasi sempre chi lo usa lo sa, e ha rimandato la questione perché non c’era mai un buon momento per affrontarla.

In questo articolo ripercorriamo la storia del ramo 5.6, spieghiamo perché è sopravvissuto così a lungo e perché, a quasi otto anni dalla fine del supporto, tenerlo esposto su Internet non è una scelta neutra. Chiudiamo con cosa si rompe nel passaggio a PHP 8, con le strade realistiche per uscirne e con un primo controllo che puoi fare da subito sul codice.

Un ramo nato nel 2014 e chiuso nel 2018

PHP 5.6.0 è uscito il 28 agosto 2014. Era l’ultimo ramo della serie 5: il successivo sarebbe stato PHP 7.0, rilasciato a dicembre 2015 con un motore riscritto e molte modifiche incompatibili. Proprio per dare più tempo a chi doveva migrare, all’inizio del 2016 il progetto ha votato un’estensione del supporto: due anni di sola sicurezza invece di uno, fino al 31 dicembre 2018. Il supporto attivo si è chiuso all’inizio del 2017, l’ultimo rilascio, PHP 5.6.40, è uscito il 10 gennaio 2019.

Linea del tempo di PHP 5.6 dal 2014 al 2026: supporto attivo dal rilascio del 28 agosto 2014 a gennaio 2017, solo sicurezza fino al 31 dicembre 2018, ultimo rilascio ufficiale 5.6.40 il 10 gennaio 2019, poi una lunga fascia rosata con la scritta nessuna patch ufficiale da quasi otto anni fino alla linea tratteggiata di settembre 2026. Sotto, i punti dei rami usciti dopo PHP 5.6: 7.0, 7.1, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2, 8.3, 8.4 e 8.5
Oltre quattro anni di supporto, quasi otto senza: nel frattempo sono usciti undici rami.

Il ramo ha quindi avuto un supporto più lungo della media dell’epoca, ed è proprio questo che lo ha reso così radicato, perché per oltre quattro anni è stato la versione “sicura” su cui sviluppare e installare. Il resto della sua storia è quella di qualunque ramo in End of Life, solo più lunga.

Perché è ancora ovunque

Il salto a PHP 7 ha rotto molte cose

PHP 7.0 ha rimosso l’estensione mysql, cioè le funzioni mysql_connect(), mysql_query() e simili, che una grande quantità di codice scritto negli anni 2000 usava per parlare con il database. Ha rimosso anche le funzioni ereg per le espressioni regolari, i tag in stile ASP e diverse funzioni minori, e ha trasformato molti errori fatali in eccezioni. Per un’applicazione scritta in quello stile, passare a PHP 7 significava riscrivere l’accesso al database e rivedere parti importanti del codice. Molti hanno preferito rimandare.

Distribuzioni e repository lo hanno reso facile

Per anni installare PHP 5.6 è stato semplice. Debian 8 lo distribuiva come versione predefinita. Su CentOS 7 e Red Hat Enterprise Linux 7, che includevano PHP 5.4, la 5.6 arrivava dalle Software Collections o dal repository Remi, e su Ubuntu da deb.sury.org. Quei server sono stati configurati una volta e poi lasciati girare, spesso sopravvivendo al sistema operativo stesso: CentOS 7 non riceve aggiornamenti da giugno 2024, e un PHP 5.6 installato lì è oggi doppiamente fuori supporto.

Applicazioni che nessuno vuole toccare

Il caso tipico è un’applicazione su misura costruita tra il 2012 e il 2017, con un framework dell’epoca o senza framework, oppure un CMS o un e-commerce di una generazione ormai chiusa a sua volta, con moduli personalizzati che legano il codice a quella versione di PHP. Chi l’ha sviluppata spesso non c’è più, la documentazione è scarsa e l’applicazione gestisce processi importanti: ordini, magazzino, fatturazione, aree riservate per i clienti. Toccarla fa paura, e la paura è comprensibile.

E soprattutto funziona

L’argomento più forte a favore dello status quo è che il sistema funziona. Il giorno dopo la fine del supporto non è cambiato nulla, e non è cambiato nulla nemmeno negli anni successivi, almeno in apparenza. Il rischio di una fine del supporto non si vede finché non diventa un incidente.

Quasi otto anni senza patch

Gran parte del codice di PHP 5.6 vive ancora, modificato, nei rami successivi: il parser delle richieste, la gestione dei file caricati, le estensioni che leggono XML, immagini, archivi e dati serializzati. Quando viene scoperta e corretta una vulnerabilità in una di queste parti, la correzione arriva sui rami supportati, mentre su PHP 5.6 il codice difettoso, se presente, resta com’è. E la pubblicazione della correzione mostra a chiunque dove guardare.

Per dare un ordine di grandezza basato sul nostro lavoro: il pacchetto PHP 5.6.40 che manteniamo corregge 55 CVE, di cui 11 aggiunte da noi con backport dedicati. Sono vulnerabilità che riguardano il codice di PHP 5.6 e che nessun rilascio ufficiale chiuderà mai. Il dettaglio di come le abbiamo trovate e corrette è nell’articolo dedicato alle 55 CVE corrette su PHP 5.6.40.

Non tutte riguardano ogni installazione. L’esposizione reale dipende dalla SAPI (PHP-FPM, mod_php o CGI), dalle estensioni caricate, dalla configurazione e da quanto il server è raggiungibile da Internet. Un PHP 5.6 su un server interno, senza accesso dall’esterno e con poche estensioni, ha un profilo di rischio molto diverso da un e-commerce pubblico. Per saperlo serve un’analisi caso per caso, da ripetere a ogni nuova vulnerabilità pubblicata.

Il problema del sistema operativo

PHP non vive da solo. PHP 5.6 è stato scritto per le librerie disponibili nel 2014, e la più critica è OpenSSL, che gestisce le connessioni cifrate verso database, servizi di pagamento, corrieri e API. PHP 5.6 supporta ufficialmente solo la serie OpenSSL 1.0.x, che il progetto OpenSSL non mantiene più; il supporto a OpenSSL 1.1 arriva con PHP 7.1 e quello a OpenSSL 3 con PHP 8.1. Le distribuzioni moderne usano OpenSSL 3: compilare PHP 5.6 su un sistema attuale richiede patch dedicate.

Il risultato è che molti PHP 5.6 restano su sistemi operativi vecchi quanto loro, con un OpenSSL fermo a una serie non più mantenuta e senza i protocolli più recenti come TLS 1.3, introdotto in OpenSSL 1.1.1. Il server diventa un insieme di componenti tutti fuori supporto, che si tengono a vicenda: non si aggiorna il sistema perché PHP non si compila, non si aggiorna PHP perché l’applicazione non è pronta.

Cosa si rompe nel passaggio a PHP 8

Da PHP 5.6 a PHP 8 non c’è un unico salto ma una serie di gradini, ciascuno documentato nelle guide di migrazione del manuale. I più rilevanti per il codice dell’epoca sono questi:

Tre colonne con le modifiche incompatibili tra PHP 5.6 e PHP 8. PHP 7.0: estensione mysql rimossa, niente più mysql_query(); funzioni ereg rimosse; tag ASP rimossi; molti errori fatali diventano eccezioni Error. PHP 7.2: mcrypt spostata in PECL; create_function() deprecata; each() deprecata. PHP 8.0: each() e create_function() rimosse; costruttori con il nome della classe non più validi; confronto tra stringa e numero cambiato, 0 uguale a foo ora è falso. In basso una fascia sul sistema operativo: PHP 5.6 è nato per OpenSSL 1.0.x, il supporto a OpenSSL 1.1 arriva con PHP 7.1, quello a OpenSSL 3 con PHP 8.1
Le modifiche che pesano di più sul codice scritto per PHP 5.6, ramo per ramo.
  • accesso al database: le funzioni mysql_* vanno sostituite con mysqli o PDO, ed è spesso il lavoro più esteso;
  • espressioni regolari: le funzioni ereg vanno convertite in PCRE, con attenzione alle differenze di sintassi;
  • crittografia: il codice basato su mcrypt va riscritto con OpenSSL o Sodium, e i dati già cifrati vanno gestiti con cura;
  • costruttori in stile PHP 4, cioè metodi con lo stesso nome della classe: da PHP 8.0 non vengono più chiamati come costruttori;
  • confronti tra stringhe e numeri: in PHP 8 0 == "foo" è falso, e un controllo che prima passava può cambiare esito senza alcun errore visibile;
  • errori più severi: avvisi che prima passavano inosservati diventano eccezioni che interrompono l’esecuzione.

Un primo controllo rapido, prima di qualsiasi stima, è contare quante volte il codice usa le funzioni rimosse. Non sostituisce un’analisi statica completa e può contare qualche falso positivo, come un metodo each() di una libreria, ma dà subito un’idea della dimensione del lavoro:

# Righe che usano funzioni rimosse in PHP 7 e PHP 8 (mysql_*, ereg, create_function, each)
grep -rnE '\bmysql_[a-z_]+\(|\beregi?(_replace)?\(|\bcreate_function\(|\beach\(' \
  --include='*.php' /var/www/sito | wc -l

# Conteggio per file, i file con più occorrenze in cima
grep -rcE '\bmysql_[a-z_]+\(|\beregi?(_replace)?\(|\bcreate_function\(|\beach\(' \
  --include='*.php' /var/www/sito | grep -v ':0$' | sort -t: -k2 -nr | head -n 20

Per un’analisi completa si usano strumenti come lo standard PHPCompatibility per PHP_CodeSniffer, che segnala le incompatibilità per ogni versione di destinazione, insieme ai test sui percorsi critici dell’applicazione.

Le strade realistiche

Per un’applicazione su PHP 5.6 le opzioni sono le stesse di qualunque ramo fuori supporto, ma i tempi sono più lunghi. La migrazione resta l’unica soluzione definitiva, e porta con sé anche un vantaggio concreto: secondo il progetto PHP, già PHP 7.0 era fino a due volte più veloce di PHP 5.6. Richiede però settimane o mesi, in base alla dimensione del codice e a quanto è coperto da test.

Nel frattempo la produzione va protetta. Le misure di contorno come l’isolamento del server, la restrizione delle aree amministrative e un web application firewall riducono la superficie esposta. Il backport delle patch di sicurezza chiude le vulnerabilità note sul ramo 5.6 senza toccare l’applicazione: ricostruiamo i pacchetti RPM o DEB a partire da quelli in uso, li proviamo in un ambiente di prova con l’applicazione reale e li rilasciamo con Ansible e un piano di rollback. Resta un ponte, perché la versione non diventa supportata e ogni nuova CVE richiede una nuova valutazione.

Da dove partire

  1. elenca i server e le applicazioni che usano PHP 5.6, verificando la versione che serve davvero ogni sito;
  2. annota il sistema operativo e l’origine dei pacchetti PHP di ciascun server;
  3. valuta l’esposizione: quali applicazioni sono raggiungibili da Internet e quali trattano dati personali o di pagamento;
  4. misura il lavoro di migrazione, partendo dal conteggio delle funzioni rimosse e da un’analisi statica;
  5. decidi come proteggere la produzione fino alla migrazione, e scrivi una data di fine per questa fase.

Possiamo dunque riassumere

PHP 5.6 è stato l’ultimo ramo della serie 5, supportato fino al 31 dicembre 2018 e chiuso con la versione 5.6.40 del gennaio 2019. È ancora diffuso perché il passaggio a PHP 7 ha rimosso funzioni usate ovunque, perché distribuzioni e repository lo hanno reso facile da installare e perché molte applicazioni costruite su di esso sono critiche e poco documentate. Non è innocuo, perché le vulnerabilità corrette dopo il 2019 nel codice condiviso restano aperte, sul solo 5.6.40 il nostro pacchetto ne chiude 55, e il ramo trascina con sé librerie e sistemi operativi altrettanto superati. La via d’uscita è una migrazione pianificata verso PHP 8, misurata con un’analisi del codice, con la produzione protetta nel frattempo da mitigazioni e backport delle patch.

IL PROSSIMO PASSO

Mettiamo
in sicurezza.

Indicaci versione di PHP, sistema operativo e cosa ti preoccupa. Ti risponderemo con una valutazione dell’esposizione e una proposta di intervento.

Richiedi supporto

Ti porta al modulo di richiesta, in quattro passi.

PHP LEGACY · MANAGED SERVER S.R.L.info@phplegacy.it +39 02 5656 9681

Lunedì – venerdì · 09:30 – 19:30

Urgenza in corso? Reperibilità H24
+39 340 985 4556 ↗