Il mio collega Franco Farnedi ha spiegato bene su francamente.tech perché PHP2Shell riguarda chiunque abbia un sito, anche chi tiene WordPress e plugin aggiornati al giorno. Qui faccio quello che faccio sempre su questo taccuino: la parte pratica. Come capire quale PHP gira davvero sul server, come aggiornarlo su ogni piattaforma che mi capita di gestire, e cosa mettere in configurazione se oggi non si può aggiornare.
- Il 21 ottobre 2026 PHP ha rilasciato 8.5.12, 8.4.27, 8.3.36 e 8.2.35, che correggono CVE-2026-109618 e CVE-2026-109619: esecuzione di codice da remoto senza autenticazione, CVSS 4.0 pari a 9,2.
- Sono esposte tutte le installazioni che servono richieste web: PHP-FPM, Apache con mod_php, php-cgi, FrankenPHP, LiteSpeed. Il rischio più alto secondo il team PHP è su mod_php.
- Le distribuzioni spesso non cambiano il numero di versione:
php -vda solo non dimostra niente, bisogna guardare il changelog del pacchetto. - Le mitigazioni in configurazione riducono il rischio ma non lo eliminano. L’unica soluzione è aggiornare e riavviare tutti i worker.
Cosa è successo, in termini tecnici
Le due falle stanno nella gestione della memoria del motore PHP, non nel codice delle applicazioni. Secondo l’advisory ufficiale:
- CVE-2026-109618 – quando una richiesta esaurisce la memoria, PHP può interrompersi mentre i dati interni della richiesta sono inizializzati solo a metà; la pulizia finale li tratta poi come validi.
- CVE-2026-109619 – uno stato interno legato alla richiesta può sopravvivere dopo che la sua memoria è stata liberata, e la richiesta successiva gestita dallo stesso worker può riusarlo prima che venga reinizializzato.
In pratica: una richiesta HTTP costruita apposta può portare il server a eseguire codice scelto dall’attaccante, e su mod_php è stato dimostrato un exploit che parte prima che venga eseguita una sola riga dell’applicazione. Firewall applicativi, plugin di sicurezza di WordPress e simili non possono correggere il motore che li fa girare.
Il rilascio era previsto per il 21 ottobre alle 14:00 UTC, con un preavviso pubblicato il giorno prima. Vista la gravità, il team PHP ha anche pubblicato backport minimali dei sorgenti per 7.4, 8.0 e 8.1, che però non sono release ufficiali.
Passo 1 – Scopri quale PHP serve davvero le pagine
Il primo errore che vedo fare è lanciare php -v e fermarsi lì. Quello è il PHP da riga di comando: il sito può girare su un’altra versione (FPM, un altro pool, un altro pacchetto del pannello). Le verifiche da fare sono tre.
Le versioni installate
# Debian / Ubuntu
dpkg -l | grep -E '^ii\s+php[0-9.]+-(fpm|cli|cgi)|libapache2-mod-php'
# RHEL / AlmaLinux / Rocky
rpm -qa | grep -E '^php|^ea-php|^alt-php' | sort
# cPanel: tutte le versioni EasyApache
for p in /opt/cpanel/ea-php*/root/usr/bin/php; do echo -n "$p "; "$p" -v | head -1; done
Quale PHP usa il web server
# Pool FPM attivi
systemctl list-units --type=service | grep -i fpm
# Apache con mod_php? (se compare php_module, è il caso più esposto)
apachectl -M 2>/dev/null | grep -i php
Se vuoi la certezza assoluta, crea un file temporaneo nella document root, aprilo dal browser e cancellalo subito dopo:
<?php echo PHP_VERSION, ' / ', PHP_SAPI;
Il numero di versione può mentire
Ubuntu e i pannelli tipo cPanel applicano la correzione come backport, cioè mantengono la versione originale e cambiano solo la release del pacchetto. Su Ubuntu 24.04, ad esempio, il PHP corretto continua a dichiararsi 8.3.6: la differenza è nel pacchetto 8.3.6-0ubuntu0.24.04.13. L’unica prova affidabile è il changelog.
# Debian / Ubuntu
zcat /usr/share/doc/php8.3-fpm/changelog.Debian.gz | grep -m3 'CVE-2026-1096'
# RHEL e derivate, cPanel (sostituisci il nome del pacchetto)
rpm -q --changelog php-cli | grep -m1 'CVE-2026-109618'
rpm -q --changelog ea-php81-php-cli | grep -m1 'CVE-2026-109618'
Se il comando non restituisce nulla, quel PHP non è corretto.
Passo 2 – Aggiorna, piattaforma per piattaforma
| Dove arriva PHP | Versione corretta da cercare | Come verificarla |
|---|---|---|
| php.net (sorgenti, Windows, Homebrew, Docker ufficiale) | 8.5.12 · 8.4.27 · 8.3.36 · 8.2.35 | numero di versione |
| Ubuntu 26.04 / 24.04 / 22.04 | 8.5.4-0ubuntu1.5 · 8.3.6-0ubuntu0.24.04.13 · 8.1.2-1ubuntu2.28 | changelog |
| Ubuntu 20.04 e precedenti | solo con Ubuntu Pro (ESM) | changelog |
| Debian 13 / Debian 12 | 8.4.27-1~deb13u1 · 8.2.35-1~deb12u1 | numero di versione |
| Debian 11 | nessuna correzione gratuita (LTS terminato) | – |
| cPanel EasyApache 4 / CloudLinux | pacchetti ea-php* e alt-php* ricostruiti | changelog |
| PPA di Ondřej Surý (Debian/Ubuntu) | build corrette anche per 5.6, 7.4, 8.0, 8.1 | changelog |
Situazione al 23 ottobre 2026; versioni e disponibilità possono cambiare, controlla sempre l’avviso del tuo fornitore.
Ubuntu e Debian
sudo apt update
apt list --upgradable 2>/dev/null | grep '^php'
# aggiorna solo i pacchetti della versione installata (esempio 8.3)
sudo apt install --only-upgrade 'php8.3*'
# riavvia chi esegue PHP
sudo systemctl restart php8.3-fpm # se usi FPM
sudo systemctl restart apache2 # se usi mod_php
Su Ubuntu 20.04 e 18.04 la correzione arriva solo con Ubuntu Pro attivo (sudo pro fix CVE-2026-109618). Su Debian 11 l’unica strada gratuita è non restarci: migra a una release supportata o usa il PPA di Surý.
RHEL, AlmaLinux, Rocky
sudo dnf update 'php*'
sudo systemctl restart php-fpm httpd
rpm -q --changelog php-cli | grep -m1 'CVE-2026-109618'
Se usi il repository di Remi: è mantenuto da volontari e il team PHP, per questa occasione, consiglia i pacchetti della distribuzione o la compilazione dai sorgenti. Controlla che il pacchetto Remi installato riporti la versione corretta prima di considerarti al sicuro.
cPanel & WHM (EasyApache 4 e CloudLinux)
cPanel non prende PHP da php.net: lo distribuisce come pacchetti ea-php propri, e CloudLinux aggiunge i suoi alt-php sotto /opt/alt. Il clic in MultiPHP Manager cambia la versione assegnata al dominio, non applica la patch.
yum clean all
yum update "ea-php*" "alt-php*"
/scripts/restartsrv_httpd
/scripts/restartsrv_apache_php_fpm
# verifica, versione per versione
rpm -q --changelog ea-php84-php-cli | grep -m1 'CVE-2026-109618'
rpm -q --changelog ea-php81-php-cli | grep -m1 'CVE-2026-109618'
yum --security. CloudLinux segnala che i metadati di sicurezza per questi pacchetti non erano ancora pubblicati, quindi un aggiornamento “solo sicurezza” può non vederli. Usa l’aggiornamento normale. Per 7.4, 8.0 e 8.1 cPanel e CloudLinux hanno fatto backport che mantengono il vecchio numero di versione: anche qui, conta il changelog.
Docker
Se PHP gira in un container, aggiornare l’host non serve a nulla: PHP è dentro l’immagine. Le immagini ufficiali php sono state ricostruite il pomeriggio stesso del rilascio.
# Dockerfile: fissa la patch, non solo il ramo
FROM php:8.4.27-fpm
# ricostruisci ignorando la cache e ricrea i container
docker compose build --pull --no-cache
docker compose up -d --force-recreate
# verifica dentro il container
docker compose exec php php -v
Due dettagli che mi hanno fatto perdere tempo: senza --pull Docker può riusare la vecchia immagine base in cache, e i tag 8.5.12RC1 o 8.4.27RC1 sono release candidate che non contengono la correzione. Per 8.1 e precedenti non esistono più tag ufficiali aggiornati. Se usi l’ambiente WordPress + Docker + Bedrock di cui ho scritto, basta aggiornare la riga FROM del container web e ricostruire.
macOS con Homebrew e Laravel Valet
Un ambiente locale non è esposto a internet come un server, ma è comunque un PHP vulnerabile che serve richieste. Homebrew ha le formule corrette per tutti i rami supportati:
brew update
brew upgrade php [email protected] [email protected] # quelle che hai installato
valet restart
php -v
Vale anche per chi segue la mia guida su WordPress in locale con Laravel Valet.
Passo 3 – Se oggi non puoi aggiornare
Il team PHP indica alcune misure di contenimento. Vanno messe in un punto che l’applicazione non può sovrascrivere: il pool FPM o la configurazione di Apache, non .user.ini e non ini_set(). Esempio per un pool FPM (/etc/php/8.3/fpm/pool.d/www.conf o il file del tuo sito):
; --- Mitigazioni temporanee PHP2Shell ---
; CVE-2026-109618: niente limite di memoria controllabile
php_admin_value[memory_limit] = -1
; corpo delle richieste piccolo (8M se il sito non riceve upload, 32M se sì)
php_admin_value[post_max_size] = 8M
php_admin_value[upload_max_filesize] = 6M
; CVE-2026-109619: disattiva l'upload progress delle sessioni
php_admin_flag[session.upload_progress.enabled] = off
; solo PHP 8.5
php_admin_flag[fatal_error_backtraces] = off
Poi riavvia tutti i worker (systemctl restart php8.3-fpm), perché le impostazioni devono valere prima che la richiesta venga letta.
Qualche avvertenza che l’advisory sottolinea e che io ripeterei tre volte:
memory_limit = -1significa che una singola richiesta può mangiarsi tutta la RAM. Metti un limite a livello di container o cgroup, possibilmente con una politica che termina solo il worker coinvolto. Non usareRLIMIT_ASoRLIMIT_DATA: possono provocare proprio il fallimento di allocazione che fa scattare la falla.- Nascondere gli errori con
display_errors,error_reportingo@non aiuta. Vanno tolte le impostazioni non valide o deprecate che generano avvisi a ogni richiesta, e corretti gli errori fatali raggiungibili dall’esterno. - Queste regole chiudono i percorsi d’attacco noti, non tutte le varianti. Se il server non si può aggiornare a breve, valuta seriamente di toglierlo da internet.
session.upload_progress.enabled=0 fino alla prossima release ordinaria, anche dopo aver aggiornato. Se l’avevi già impostato, lascialo così. WordPress di suo non usa questa funzione.
Passo 4 – Verifica e controlla che nessuno sia entrato
Gli attacchi sono partiti prima delle patch, quindi chi era esposto il 20 e il 21 ottobre deve fare anche un controllo a posteriori. Qualche punto di partenza:
# il servizio è stato davvero riavviato dopo l'aggiornamento?
systemctl status php8.3-fpm | grep -i active
# file PHP creati o modificati dal 20 ottobre nella document root
find /var/www -type f -name '*.php' -newermt '2026-10-20' -ls
# picchi di errori di memoria nei log (indizio di tentativi su CVE-2026-109618)
grep -i 'allowed memory size' /var/log/php8.3-fpm.log | tail -50
# utenti amministratore WordPress creati di recente
wp user list --role=administrator --fields=ID,user_login,user_registered
Se trovi qualcosa di strano e dal sito possono essere usciti dati personali, ricorda che il GDPR prevede la notifica al Garante entro 72 ore.
Checklist finale
- Elenca tutte le versioni PHP installate, non solo quella della CLI.
- Individua quale SAPI e quale versione servono ciascun sito (FPM, mod_php, container).
- Aggiorna dal canale giusto: distribuzione, pannello, immagine Docker o Homebrew.
- Riavvia FPM, Apache o i container. Un pacchetto aggiornato con i worker vecchi in memoria non protegge niente.
- Verifica con il changelog del pacchetto, non con
php -v. - Lascia
session.upload_progress.enabled=0fino alla prossima release. - Se sei su 8.1 o precedenti, pianifica la migrazione a 8.3 o 8.4. La 8.2 esce dal supporto il 31 dicembre 2026.
- Controlla file, log e utenti per eventuali compromissioni.
Se ti sei trovato in una situazione diversa da quelle che ho descritto (Plesk, Windows Server con IIS, qualche hosting particolare), scrivimi: aggiungo la sezione.
Fonti
- PHP: security advisory del 21 ottobre 2026 · avviso informativo del 23 ottobre
- Franco Farnedi, francamente.tech: PHP2Shell: quando il problema non è il tuo sito
- Sansec: PHP2Shell: PHP RCE
- Mattias Geniar: how to apply the patches (stato dei pacchetti per distribuzione)
- ComputingForGeeks: Ubuntu · cPanel e CloudLinux
- Imunify360 / CloudLinux: pacchetti ea-php e alt-php corretti
- Docker: How to Fix PHP2Shell · IT-Connect: PHP2Shell e Docker
- Garante Privacy: violazioni di dati personali