PHP2Shell

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.

In breve
  • 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 -v da 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 PHPVersione corretta da cercareCome verificarla
php.net (sorgenti, Windows, Homebrew, Docker ufficiale)8.5.12 · 8.4.27 · 8.3.36 · 8.2.35numero di versione
Ubuntu 26.04 / 24.04 / 22.048.5.4-0ubuntu1.5 · 8.3.6-0ubuntu0.24.04.13 · 8.1.2-1ubuntu2.28changelog
Ubuntu 20.04 e precedentisolo con Ubuntu Pro (ESM)changelog
Debian 13 / Debian 128.4.27-1~deb13u1 · 8.2.35-1~deb12u1numero di versione
Debian 11nessuna correzione gratuita (LTS terminato)–
cPanel EasyApache 4 / CloudLinuxpacchetti ea-php* e alt-php* ricostruitichangelog
PPA di Ondřej Surý (Debian/Ubuntu)build corrette anche per 5.6, 7.4, 8.0, 8.1changelog

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'
Attenzione con 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 = -1 significa 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 usare RLIMIT_AS o RLIMIT_DATA: possono provocare proprio il fallimento di allocazione che fa scattare la falla.
  • Nascondere gli errori con display_errors, error_reporting o @ 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.
Aggiornamento del 23 ottobre. PHP ha pubblicato un avviso informativo su un ulteriore vettore, poco probabile, legato all’upload progress delle sessioni (CVE-2026-115560). Il consiglio è tenere 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

  1. Elenca tutte le versioni PHP installate, non solo quella della CLI.
  2. Individua quale SAPI e quale versione servono ciascun sito (FPM, mod_php, container).
  3. Aggiorna dal canale giusto: distribuzione, pannello, immagine Docker o Homebrew.
  4. Riavvia FPM, Apache o i container. Un pacchetto aggiornato con i worker vecchi in memoria non protegge niente.
  5. Verifica con il changelog del pacchetto, non con php -v.
  6. Lascia session.upload_progress.enabled=0 fino alla prossima release.
  7. 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.
  8. 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


Precedente