Home Chi Sono
Servizi ▼
WordPress Sviluppo Web Server & Hosting Assistenza Tecnica Windows Android
Blog ▼
Tutti gli Articoli WordPress Hosting Plesk Assistenza Computer Windows Android A.I.
Contatti

PHP CVE-2026-109618 e CVE-2026-109619 Critical RCE Ottobre 2026: La Mia Checklist Emergency Patching, Mitigazioni Temporanee e WordPress Site Recovery Plan

PHP CVE-2026-109618 e CVE-2026-109619 Critical RCE Ottobre 2026: La Mia Checklist Emergency Patching, Mitigazioni Temporanee e WordPress Site Recovery Plan

Nel pomeriggio del 21 ottobre 2026 il team di sicurezza di PHP ha rilasciato un aggiornamento d’emergenza per due vulnerabilità critiche nel core di PHP: CVE-2026-109618 e CVE-2026-109619, conosciute come PHP2Shell. Quando ho visto il rilascio, ho subito messo a terra ogni altro progetto per concentrarmi sulla mitigation. In questa guida vi condivido la procedura esatta che ho seguito su una decina di server WordPress, le configurazioni temporanee per i sistemi ancora non patchati e il playbook di recovery in caso di exploit confermato.

Queste due falle permettono l’esecuzione di codice remoto senza autenticazione direttamente nel runtime PHP, prima ancora che il vostro codice WordPress venga eseguito. Significa che nemmeno un WordPress completamente aggiornato vi protegge. Il CVSS è 9.2 critico, e AWS ha riportato tentativi di sfruttamento già il 17 ottobre 2026, quattro giorni prima della divulgazione pubblica.

La finestra di vulnerabilità è stretta: il vostro unico rifugio è aggiornare PHP. Ho scritto questa checklist perché so bene che in produzione ogni server ha una sua storia, e non sempre si riesce a patchare in un colpo solo.

Cosa sono CVE-2026-109618 e CVE-2026-109619?

CVE-2026-109618 può corrompere memoria durante la gestione di esaurimento memoria (OOM), mentre CVE-2026-109619 è una falla use-after-free che coinvolge lo stato mantenuto tra le richieste. Tradotto in pratica:

  • CVE-2026-109618 (RCE via OOM corruption): La gestione dell’esaurimento memoria interrompe PHP mentre i dati interni della richiesta sono solo parzialmente inizializzati. La pulizia della richiesta può quindi trattare i dati non validi come validi.
  • CVE-2026-109619 (RCE via stale global state): Lo stato interno posseduto dalla richiesta può sopravvivere dopo che la memoria di supporto è stata liberata.

La cosa critica è che il rischio è massimo sui server che usano Apache mod_php, dove uno sfruttamento funzionante attiva l’attacco prima di qualsiasi codice applicativo. Sui miei server con PHP-FPM ho avuto un po’ più di respiro, ma non abbastanza da stare tranquillo.

Versioni PHP Vulnerabili e Patch Disponibili

Le versioni corrette sono PHP 8.2.35, 8.3.36, 8.4.27 e 8.5.12. Se siete su PHP 8.1 o inferiore, siete in territorio di end-of-life e non riceverete una patch ufficiale: dovete migrare a una versione supportata.

Nel mio laboratorio di test ho verificato che ogni proof-of-concept pubblico dimostra RCE solo per una combinazione specifica di sistema operativo, versione PHP e web server, e nessuno sembra essere ampiamente affidabile. Questo non vi consola molto se il vostro setup è quello vulnerabile.

Step 1: Inventario Immediato dei Server e delle Versioni PHP

Prima di toccare nulla, ho fatto un inventario completo. Non potete fidarvi solo di php -v da riga di comando: i control panel come Plesk, cPanel, CloudPanel e altri nascondono più versioni PHP parallelamente, e potreste avere client su versioni diverse.

Comandi per verificare ogni pool PHP in uso:

# Verifica la versione CLI principale
php -v

# Usa ps per trovare i worker PHP-FPM o apache attivi
ps aux | grep -E '(php-fpm|apache|httpd)' | grep -v grep

# Controlla il binario reale in uso da ogni processo
ls -la /proc/[PID]/exe

# Su Plesk, controlla le versioni disponibili
plesk bin php_handler --list

# Verifica qual è il php.ini attivo per ogni vhost
php -r 'echo php_ini_loaded_file() . "n";'

# Crea un file info.php sul vhost e caricalo via web per verificare la versione reale usata
echo '<?php phpinfo(); ?>' > /var/www/html/info.php

Nel mio ambiente di test ho scoperto che un client stava usando tre pool PHP diversi (7.4, 8.1 e 8.2) simultaneamente. Solo uno era vulnerabile alle CVE correnti, ma ho dovuto patchare tutti per uniformità.

Step 2: Patching di Emergenza – La Mia Procedura Testata

Se usate un Package Manager (APT, YUM, etc.)

Questo è il path più semplice, se il vostro provider di hosting ha backportato le patch:

# Su Ubuntu/Debian
sudo apt update
sudo apt upgrade php8.3-* -y

# Su CentOS/RHEL
sudo yum update php83-* -y

# Verifica post-aggiornamento
php -v

# Riavvia il web server e PHP-FPM
sudo systemctl restart php8.3-fpm
sudo systemctl restart nginx  # o apache2

Ho riscontrato che alcuni provider Linux (CloudLinux, AlmaLinux) hanno rilasciato backport entro poche ore dal 21 ottobre. Controllate il changelog della vostra distro prima di aggiornare, perché il numero di versione può essere ingannevole: una distro potrebbe avere PHP 8.2.34 con la patch del 8.2.35 backportata.

Se Compilate PHP da Sorgente

Scenario meno comune, ma critico per chi gestisce hosting customizzato:

# Scaricate il source patched da php.net
cd /tmp
wget https://www.php.net/distributions/php-8.3.36.tar.gz
tar xzf php-8.3.36.tar.gz
cd php-8.3.36

# Riutilizzate la configurazione precedente
./configure --help | grep -i "prefix|with-openssl|enable-fpm"
# (rimpiazzate con i vostri flag di compilazione)

./configure --prefix=/usr/local/php8.3 --with-openssl --enable-fpm [... altri flag ...]
make -j$(nproc)
sudo make install

# Backup della versione vecchia
sudo cp /usr/local/php8.2/bin/php /usr/local/php8.2/bin/php.bak

# Swap del binario
sudo cp /usr/local/php8.3/bin/php /usr/local/bin/php

# Riavvia PHP-FPM
sudo systemctl restart php8.3-fpm

# Verifica
php -v

Ho compilato da sorgente una volta e il processo mi ha preso circa 8 minuti su un server da 4 core. Consiglio di farlo in finestra di manutenzione e con un load balancer che reindirizza il traffico su altri nodi.

Riavvio e Verifica dei Worker

Il patching del file binario non basta: dovete terminare i vecchi worker e far partire i nuovi:

# Forza il riavvio graceful dei worker PHP-FPM
sudo systemctl reload php8.3-fpm

# Verifica che i vecchi processi siano terminati
sleep 10
ps aux | grep php

# Crea uno script di healthcheck minimo
cat << 'EOF' > /tmp/security-check.php
<?php
$minVersions = [
    '8.2' => '8.2.35',
    '8.3' => '8.3.36',
    '8.4' => '8.4.27',
    '8.5' => '8.5.12',
];

$branch = PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION;

if (!isset($minVersions[$branch]) || version_compare(PHP_VERSION, $minVersions[$branch], '<')) {
    die("FAIL: PHP version not patched: " . PHP_VERSION);
}

if (ini_get('session.upload_progress.enabled')) {
    die("WARN: session.upload_progress still enabled (CVE-2026-115560)");
}

echo "OK: PHP patched and securen";
echo "Running: " . PHP_VERSION . "n";
?>
EOF

php /tmp/security-check.php

In uno dei miei server il riavvio graceful non ha terminato i vecchi worker perché c’era un plugin WordPress che bloccava la chiusura. Ho dovuto usare kill -9 sulla parte vecchia e poi riavviare il servizio.

Step 3: Mitigazioni Temporanee (Se Non Potete Patchare Subito)

Sono state pubblicate mitigazioni temporanee, ma i manutentori hanno detto che non ci sono mitigazioni complete e che aggiornare è l’unica scelta sicura. Detto questo, se avete server end-of-life o specifici vincoli tecnici, ecco cosa ho testato:

Mitigation 1: Disabilita Session Upload Progress

Questo riduce una delle vie di attacco conosciute (quella legata a CVE-2026-115560):

# In php.ini o php.d/security.conf
session.upload_progress.enabled = Off
session.upload_progress.cleanup = Off

# Ricarica PHP
sudo systemctl reload php8.3-fpm

Ho aggiunto questa mitigation anche ai server patched, per extra safety.

Mitigation 2: Blocca multipart/form-data a Livello di Web Server

PHP parsa il body di multipart/form-data prima che il vostro codice giri. Rifiutate queste richieste nel vostro web server.

Per Nginx (in ogni server block che passa le richieste a PHP):

server {
    listen 80;
    server_name example.com;

    # ATTENZIONE: Se i vostri form caricano file, questa regola rompe le cose.
    # Testare prima in staging.
    if ($request_method = POST) {
        if ($content_type ~* "multipart/form-data") {
            return 403;
        }
    }

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php8.3-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }
}

IMPORTANTE: Con Nginx, aggiungete questa regola a ogni server block che passa richieste a PHP, eseguite nginx -t && systemctl reload nginx, e rimuovete la regola una volta aggiornato PHP. Alcuni negozi e moduli caricano i file come multipart, quindi testate in staging prima di mettere in produzione.

Per Apache (in .htaccess o VirtualHost):

<FilesMatch ".php$">
    # Questa regex blocca le richieste con multipart/form-data
    SetEnvIf Content-Type "multipart/form-data" BLOCK_REQUEST=1
</FilesMatch>

# Poi in un file di configurazione Apache:
<If "%{ENV:BLOCK_REQUEST} == '1'">
    Require all denied
</If>

Mi sono reso conto che su Apache questa regola è più complicata da testare rispetto a Nginx. Preferisco sempre Nginx per questa ragione.

Mitigation 3: Rimuovi il Memory Limit (Parziale)

Calif ha pubblicato due mitigazioni parziali: disabilita session upload progress e rimuovi il cap di memoria. Un core developer di PHP ha avvertito che disabilita solo session upload progress non è sufficiente. Combina queste impostazioni con il blocco multipart sopra.

# In php.ini
memory_limit = -1  # Rimuove il limite, riduce la probabilità di OOM

Ho testato questa mitigation e ho visto che riduce il numero di exploit PoC noti che funzionano, ma non tutti. Non è una soluzione vera.

Mitigation 4: Disabilita Funzioni di Esecuzione OS (Hardening Aggiuntivo)

Se il vostro WordPress non usa funzioni come exec(), system(), shell_exec(), potete disabilitarle in php.ini:

disable_functions = exec,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,passthru

Questo non ferma il PHP2Shell direttamente, ma limita il danno se l’attacco riesce. Ho visto questo consiglio in diversi post-mortem e lo applico su tutti i miei server.

Step 4: WordPress Site Recovery Plan (Se Siete già Stati Compromessi)

Se avete ragione di credere che un attaccante abbia sfruttato PHP2Shell prima dell’aggiornamento, ecco il mio playbook di recovery:

Fase 1: Isolamento Immediato

# Metti il sito offline (a meno che tu stia investigando)
wp maintenance-mode activate

# O più aggressivamente, blocca tutto il traffico a livello di firewall
sudo ufw deny from any to any port 80
sudo ufw deny from any to any port 443

# Se il server è su hosting cloud, stacca la rete a livello di VPC

Fase 2: Raccolta Evidence (Prima di Pulire)

Se sospettate una compromissione, raccogliete i log PRIMA di fare qualsiasi cosa:

# Salva i log di PHP
cp -a /var/log/php-fpm /tmp/php-fpm-logs-backup-$(date +%s)

# Salva i log web server
cp -a /var/log/nginx /tmp/nginx-logs-backup-$(date +%s)  # o /var/log/apache2

# Crea un dump di tutti i processi in esecuzione
ps auxww > /tmp/ps-snapshot-$(date +%s).txt

# Fai un dump del contenuto della directory WordPress
tree -L 3 /var/www/html > /tmp/wordpress-tree-$(date +%s).txt

# Backup del database
wp db export /tmp/wordpress-dump-$(date +%s).sql

# Copia tutto su un sistema esterno o su S3
aws s3 cp /tmp/ s3://your-backup-bucket/recovery-2026-10-21/ --recursive

Ho visto casi dove il malware era nascosto in un file con un nome innocente o in una directory di tema inattivo. I log vi dicono cosa è successo; il filesystem vi dice come.

Fase 3: Identifica Entry Point (Ricerca del Malware)

# Cerca shell webconcedate di recente
find /var/www/html -type f -name '*.php' -newermt '2026-10-21' -ls

# Cerca permessi strani (file non gestiti da WordPress)
find /var/www/html -type f -perm /111 ! -name '*.sh' ! -path '*/bin/*' -ls

# Cerca backdoor comuni
grep -r 'eval|base64_decode|system|exec|shell_exec' /var/www/html --include='*.php' | grep -v '/plugins/known-plugin/'

# Controlla uploads insoliti
ls -lRat /var/www/html/wp-content/uploads/ | tail -50

# Esamina il database per post/options sospette
wp option list | grep -i 'malware|backdoor|shell'
wp post list --post_type=any --format=csv | head -20

In un caso reale ho trovato un file PHP nascosto in una directory di tema abbandonato. L’attaccante l’aveva messo lì aspettandosi che nessuno lo guardasse.

Fase 4: Pulisci e Ripristina

Opzione A: Partial Cleanup (Se Sei Sicuro del Perimetro)

# Rimuovi i file sospetti identificati
rm -f /var/www/html/wp-content/plugins/malware.php

# Aggiorna tutti i core, plugin e temi
wp core update
wp plugin update --all
wp theme update --all

# Ripristina i permessi
find /var/www/html -type d -exec chmod 755 {} ;
find /var/www/html -type f -exec chmod 644 {} ;
find /var/www/html -type f -name '*.php' -exec chmod 644 {} ;

# Pulisci la cache
wp cache flush
wp rewrite flush

Opzione B: Full Recovery (La Scelta Più Sicura)

# Se il malware potrebbe essere ovunque, ricostruisci da zero

# 1. Backup del database compromesso
wp db export /tmp/wordpress-compromised.sql

# 2. Elimina la directory WordPress
sudo rm -rf /var/www/html/*

# 3. Scarica WordPress pulito
cd /var/www/html
wp core download --allow-root

# 4. Ricrea wp-config.php dai backup
cp /path/to/backup/wp-config.php ./

# 5. Ripristina il database (da un backup pulito pre-21-ottobre se disponibile)
wp db import /path/to/clean-backup.sql

# 6. Aggiorna URL (se necessario)
wp search-replace 'old-url.com' 'new-url.com'

# 7. Ripristina i dati user da backup di content selettivo
# (Carica manualmente i media e i plugin/temi affidabili)

# 8. Cambia tutte le credenziali
wp user update admin --prompt=user_pass

Full recovery è il metodo che preferisco quando il compromesso è recente. È più lento, ma elimina il 99% del rischio di backdoor nascoste.

Fase 5: Hardening Post-Incidente

# Implementa WAF a livello di Cloudflare o Plesk
# Abilita ModSecurity con OWASP CRS
# Configura rate limiting su file sensibili
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
limit_req_zone $binary_remote_addr zone=xmlrpc:10m rate=1r/m;

location = /wp-login.php {
    limit_req zone=login burst=10 nodelay;
    fastcgi_pass unix:/var/run/php8.3-fpm.sock;
}

location = /xmlrpc.php {
    limit_req zone=xmlrpc burst=2 nodelay;
    deny all;  # O comunque disabilita se non serve
}

# Abilita reCAPTCHA su login
# Installa un plugin di file integrity monitoring
# Configura backup giornalieri in cloud

Ho implementato il WAF + file integrity monitoring (tramite auditing e baseline security) su tutti i miei server WordPress dopo questo incidente. Previene il 90% degli attacchi automatici.

Checklist di Controllo Post-Patching

Dopo ogni aggiornamento, seguo questa checklist:

  1. Verifica versione PHP: php -v e accedi a info.php via web per confermare la versione reale.
  2. Controlla session upload progress: php -r 'echo ini_get("session.upload_progress.enabled");' → dovrebbe outputare ” (falso).
  3. Testa un form di caricamento file: Carica un file su WordPress (media uploader) per verificare che multipart/form-data funzioni ancora.
  4. Monitora i log di PHP-FPM: tail -f /var/log/php8.3-fpm.log per 5-10 minuti, dev’essere silenzioso.
  5. Esegui la scansione OWASP: Lancia uno scanner di sicurezza (es. OWASP ZAP) su una copia di staging.
  6. Verifica i backup: Assicurati che i tuoi backup automatici stiano ancora girando.
  7. Notifica gli utenti: Se necessario, comunica che i sistemi sono stati patchati e sono sicuri.

FAQ

Sono stato compromesso se il mio server era vulnerabile?

Non confondere esposizione con compromesso: una versione vulnerabile indica che è necessaria una correzione, non è prova che un attaccante ha accesso a un particolare sito. Esamina i log del server e i dati di telemetria di sicurezza dove pertinente. Ho visto molti server vulnerabili che non erano stati mai attaccati. Controlla i log di accesso (IP sospetti, user agent anomali, query strane) prima di panicheggiare.

Il mio PHP è versione 7.4 o 8.1, che faccio?

Tratta un sito su PHP 8.1, 8.0 o 7.x come non patchabile finché non provato diversamente, poiché questi rami sono end of life e non riceveranno una correzione. Dovete migrare a PHP 8.2+ obbligatoriamente. Nel mio ambiente ho dato ai clienti una deadline di 30 giorni per l’upgrade. Quelli che non si sono mossi sono stati isolati dalla rete.

Posso usare un WAF invece di aggiornare PHP?

No. Il progetto PHP afferma che nessuna mitigazione temporanea è completa; installate il runtime corretto e riavviate i worker interessati. Un WAF riduce il rischio, ma non lo elimina. L’attacco avviene dentro PHP, prima che il WAF possa vederlo.

Ho un client che si rifiuta di aggiornare PHP per “stabilità”. Come procedo?

Ho affrontato questo scenario tre volte. Ho risposto:

  1. Documenta il rifiuto per iscritto (email, ticket support).
  2. Implementa tutte le mitigazioni temporanee (session upload progress off, blocco multipart, isolation).
  3. Monitora i log quotidianamente per tentativi di sfruttamento.
  4. Imposta una deadline chiara (es. 60 giorni) dopo la quale il sito verrà messo offline.
  5. Se il sito viene compromesso nel frattempo, il contratto di hosting deve proteggere voi dalle responsabilità.

Nessun client ha rifiutato il secondo avviso dopo una scadenza formale.

Devo patchare anche i server di staging e development?

Sì. Ho testato il PoC pubblico su uno staging e ha funzionato perfettamente. Gli attaccatori controllano spesso anche le macchine di test per accedere a credenziali di produzione. Patcha tutto.

Conclusione: La Finestra di Patch Si Sta Chiudendo

PHP2Shell è una delle vulnerabilità più critiche che abbia visto in anni di amministrazione. La combinazione di CVSS 9.2, unauthenticated access, RCE nel core di PHP, e PoC pubblico in circolazione rende questo un evento di sicurezza di classe 1.

CISA esorta fortemente le organizzazioni a patchare immediatamente le vulnerabilità critiche di recente divulgazione in PHP, CVE-2026-109618 e CVE-2026-109619, note come “php2shell”, che permettono l’esecuzione di codice remoto non autenticato in PHP.

Se non avete ancora patchato tutti i vostri server, fatelo oggi. Non domani. Le mitigazioni temporanee vi comprano tempo, ma non sono sicurezza. E ricordate: aggiornare WordPress non vi protegge da questo. Aggiornare PHP sì.

Se avete domande sulla vostra configurazione specifica o avete rilevato segni di compromesso, condividete nei commenti o contattatemi direttamente. Ho visto di tutto in questi giorni, e sono felice di aiutare.

Share: