---
title: "La scoperta di PHP2Shell e cosa fare sulle CVE-2026-109618 e CVE-2026-109619"
description: "Hanno una correzione tutti i rami di PHP, 5.6 compreso, ma su Debian e Ubuntu passa dai pacchetti sury e il numero di versione resta quello di prima."
canonical: "https://www.mauriziofonte.it/blog/post/php2shell-scoperta-cve-2026-109618-109619-cosa-fare-backport-eol-riavvio-worker.html"
author: "Maurizio Fonte"
date: "2026-10-21T08:19:34+02:00"
modified: "2026-10-21T08:19:34+02:00"
section: "PHP"
tags: ["PHP", "Linux & Server"]
license: "Riuso e citazione consentiti con attribuzione e link alla fonte"
---

[PHP](https://www.mauriziofonte.it/blog/cat/php.html) [Linux & Server](https://www.mauriziofonte.it/blog/cat/linux.html)

# [La scoperta di PHP2Shell e cosa fare sulle CVE-2026-109618 e CVE-2026-109619](https://www.mauriziofonte.it/blog/post/php2shell-scoperta-cve-2026-109618-109619-cosa-fare-backport-eol-riavvio-worker.html)

Mercoledì 21 Ottobre 2026, alle 08:19 ![La scoperta di PHP2Shell e cosa fare sulle CVE-2026-109618 e CVE-2026-109619](https://www.mauriziofonte.it/image/006150200-php2shell-scoperta-cve-2026-109618-109619-cosa-fare-backport-eol-riavvio-worker.jpg)

Il 20 ottobre 2026 il progetto PHP ha fatto una cosa che fa di rado: ha annunciato una release di sicurezza prima di pubblicarla, dicendo che avrebbe corretto due vulnerabilità critiche valutate entrambe 9.2 su CVSS 4.0 e invitando tutti a prepararsi. Nello stesso annuncio c'era una riserva insolita, che con il senno di poi suona come una previsione: ci riserviamo di rilasciare prima, se i dettagli diventano pubblici o se compare evidenza di sfruttamento.

Accaddero entrambe le cose nel giro di poche ore. La sera del 20 i dettagli trapelarono, una società di sicurezza confermò pubblicamente che le vulnerabilità erano reali, e il giorno dopo, alle 14:00 UTC, uscirono le versioni corrette con un giorno di anticipo sull'embargo concordato. Gli avvisi erano stati pubblicati ventisei minuti prima, alle 13:34 UTC: **CVE-2026-109618** e **CVE-2026-109619**, che i ricercatori hanno battezzato insieme **PHP2Shell**.

Questo è il primo pezzo di una serie di cinque. Qui c'è come ci si è arrivati e cosa fare adesso sulle macchine che amministri, con i tre controlli che in questo caso valgono più del numero di versione. Gli altri quattro scendono nel dettaglio del difetto e di come si vede arrivare il traffico che lo cerca.

## TL;DR

> - **Sono corretti tutti i rami, 5.6 compreso.** Release ufficiali `8.2.35`, `8.3.36`, `8.4.27`, `8.5.12`; su Debian e Ubuntu i pacchetti sury correggono anche `5.6`, `7.0`, `7.1`, `7.2`, `7.3`, `7.4`, `8.0` e `8.1`.
> - **Il numero di versione mente:** sui rami fuori supporto il backport lascia `7.4.33` o `8.1.34`. Si verifica dal changelog del pacchetto, mai da `php -v`.
> - **Fuori da Debian e Ubuntu la copertura si ferma ai rami supportati:** su famiglia Red Hat e su Alpine non esiste un equivalente di sury per i rami morti.
> - **Il pacchetto non basta:** finché non riavvii, i worker in esecuzione servono richieste con il codice vecchio. Vale anche per i processi PHP long-running da riga di comando.
> - **Chiedilo al processo giusto:** la CLI e il pool FPM possono girare versioni e configurazioni diverse. Conta la seconda.
> - **Se aggiungi un limite di memoria cgroup**, metti anche `OOMPolicy=continue`: il default `stop` ferma l'intero servizio invece del singolo worker.

## Chi ha trovato PHP2Shell, e come

La scoperta non appartiene a un gruppo solo, ed è la ragione per cui gli avvisi elencano quattro segnalatori diversi. La prima segnalazione al team di sicurezza di PHP arriva l'11 agosto 2026 da Calif, una piccola realtà di ricerca offensiva. Tredici giorni dopo, il 24 agosto, arriva una seconda segnalazione indipendente da Wiz Research, che nel frattempo aveva già dimostrato esecuzione di codice non autenticata contro installazioni standard di Drupal e di WordPress. Nello stesso gruppo di crediti compaiono il team di sicurezza di OpenAI e, secondo la ricostruzione pubblicata da Cloudflare, anche Quarkslab.

Il dettaglio che ha fatto discutere riguarda il metodo. Wiz ha dichiarato di aver trovato la prima delle due vulnerabilità usando modelli linguistici di frontiera come strumento di analisi del codice, e ha accompagnato la dichiarazione con una frase da maneggiare con le pinze: un singolo ricercatore avrebbe completato in una settimana quello che a una squadra di livello mondiale avrebbe richiesto mesi. È un'affermazione dell'autore, non una misura verificabile da fuori, e la pubblicità del fornitore e il risultato tecnico qui viaggiano sullo stesso foglio.

Quello che invece si può verificare è il resto, e conviene tenerlo separato dal titolo.

**Cronologia: Dalla prima segnalazione alla pubblicazione di PHP2Shell**

*Situazione al 24 ott 2026*

1. 11 ago 2026, già avvenuto: Prima segnalazione al team di sicurezza di PHP, da Calif
2. 24 ago 2026, già avvenuto: Seconda segnalazione indipendente, da Wiz Research

  Esecuzione di codice non autenticata già dimostrata contro Drupal e WordPress
3. 21 set 2026, già avvenuto: Il team PHP conferma le segnalazioni e avvia la correzione coordinata
4. 17 ott 2026, già avvenuto: [Primo tentativo osservato da Amazon, quattro giorni prima della divulgazione](https://aws.amazon.com/blogs/security/amazon-threat-intelligence-identifies-php2shell-exploitation-prior-to-public-disclosure-in-madpot/)
5. 18 ott 2026, già avvenuto: Viene firmato il commit che corregge entrambe le vulnerabilità
6. 20 ott 2026, già avvenuto: Annuncio preventivo di php.net, poi fuga di notizie sui dettagli
7. 21 ott 2026, già avvenuto: 13:34 UTC avvisi, 14:00 UTC release, un giorno prima dell'embargo
8. 23 ott 2026, già avvenuto: Avviso informativo su CVE-2026-115560, che riguarda anche le versioni corrette

Fonte: php.net, avvisi GHSA, blog dei ricercatori, ottobre 2026

Due righe di questa cronologia meritano più attenzione del resto.

La prima è quella del 17 ottobre. Amazon ha documentato un tentativo intercettato dalla propria rete di sensori quattro giorni prima della divulgazione, da un'infrastruttura di anonimizzazione commerciale, e ha scritto di non sapere come l'autore fosse arrivato a quelle informazioni. La conclusione operativa che ne ha tratto è la cosa più utile dell'intero documento: **non si deve dare per scontato che la data di divulgazione sia la prima data di sfruttamento**. Chi apre un'indagine su questa vicenda dovrebbe partire dal 17 ottobre, non dal 21.

La seconda è quella del 23 ottobre, due giorni dopo la pubblicazione, quando è uscito un avviso informativo su un terzo problema collegato, **CVE-2026-115560**, che riguarda anche le versioni già corrette e che sarà risolto con la prossima release ordinaria. Le condizioni per incontrarlo sono insolite e dipendono da come l'applicazione cambia un parametro delle sessioni a runtime, ma la contromisura è la stessa che conviene comunque tenere, cioè disattivare il meccanismo di avanzamento degli upload se non lo usi.

## Che cosa sono le due vulnerabilità

**Vulnerabilità: Corruzione dello stato della richiesta su esaurimento della memoria**

CVE-2026-109618, CVSS 9,2 su 10, gravità Critica

- **Debolezza**: [CWE-416](https://cwe.mitre.org/data/definitions/416.html)
- **Pubblicata**: 21 ott 2026
- **Correzione**: 21 ott 2026

Vettore CVSS 4.0

`CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N`

- **Vettore d'attacco**: Rete
- **Complessità**: Alta
- **Requisiti d'attacco**: Presenti
- **Privilegi richiesti**: Nessuno
- **Interazione utente**: Nessuna
- **Riservatezza**: Alto
- **Integrità**: Alto
- **Disponibilità**: Alto
- **Riservatezza a valle**: Nessuno
- **Integrità a valle**: Nessuno
- **Disponibilità a valle**: Nessuno

| Prodotto | Versioni colpite | Corretta in |
| --- | --- | --- |
| PHP 8.2 | fino a 8.2.34 | 8.2.35 |
| PHP 8.3 | fino a 8.3.35 | 8.3.36 |
| PHP 8.4 | fino a 8.4.26 | 8.4.27 |
| PHP 8.5 | fino a 8.5.11 | 8.5.12 |

Fonte: php.net, ottobre 2026

Verificato: 24 ott 2026

Approfondisci: [NVD](https://nvd.nist.gov/vuln/detail/CVE-2026-109618), [Avviso GHSA-w8hw-w9fx-j79w](https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w), [Annuncio su php.net](https://www.php.net/archive/2026.php)

La seconda, **CVE-2026-109619**, ha lo stesso punteggio, le stesse versioni corrette e un meccanismo diverso: riguarda stato interno che sopravvive al termine di una richiesta e viene toccato da quella successiva servita dallo stesso processo. Il suo [avviso](https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp) è il gemello del primo, e i due si rimandano a vicenda nelle raccomandazioni: chi applica le indicazioni di uno e ignora l'altro resta esposto.

Il National Vulnerability Database le valuta diversamente fra loro sulla scala 3.1, 9.8 la prima e 8.1 la seconda, perché la seconda richiede che due richieste finiscano sullo stesso processo. Red Hat, che sulle proprie distribuzioni parte da una configurazione in cui l'interprete gira in processo separato, le classifica come importanti anziché critiche per lo stesso motivo. Per la decisione operativa la differenza non conta: le corregge lo stesso aggiornamento, e la riduzione di rischio della configurazione a processi separati vale per una delle due, non per entrambe.

Una cosa che aiuta a dimensionare il problema: nessuna delle due, al momento in cui scrivo, è nel catalogo delle vulnerabilità sfruttate attivamente della CISA. Chi usa quel catalogo come innesco dell'urgenza, e sono molte organizzazioni strutturate, in questo caso parte in ritardo, perché i tentativi documentati da più fonti indipendenti sono cominciati prima della pubblicazione degli avvisi. Il motivo per cui quel catalogo arriva spesso tardi, con i numeri di dodici anni di osservazioni, è il tema del [terzo pezzo della serie](https://www.mauriziofonte.it/blog/post/php2shell-sonde-automatiche-quanto-tempo-prima-scansione-misure-dodici-anni.html).

## Perché il numero di versione non dice se sei aggiornato?

Perché sui rami fuori supporto la correzione arriva come backport sul pacchetto della distribuzione, e il backport **non cambia la versione upstream**. Un server con `PHP 7.4.33` può essere corretto o vulnerabile, e `php -v` restituisce la stessa stringa nei due casi.

Il progetto PHP rilascia una versione nuova solo per i rami in supporto, che oggi sono 8.2, 8.3, 8.4 e 8.5. Per tutto il resto il canale è un altro: chi mantiene i pacchetti prende la correzione, la adatta al codice del ramo vecchio e pubblica una nuova **revisione del pacchetto**, lasciando intatto il numero di versione di PHP. L'informazione su cui tutti si basano diventa muta proprio dove serve di più.

Data la gravità, in questo caso i canali disponibili sono parecchi.

**Matrice di confronto: Dove trovare la correzione di PHP2Shell, ramo per ramo**

*Revisioni verificate sui changelog dei pacchetti; il numero di versione upstream resta invariato*

| Ramo | Release ufficiale php.net | Backport da sorgente php.net | Pacchetti sury |
| --- | --- | --- | --- |
| 8.2 - 8.5 | Sì, 8.2.35, 8.3.36, 8.4.27, 8.5.12 | N.d. | Sì |
| 8.1 | No, fuori supporto dal 2025-12-31 | Sì | Sì, 8.1.34-9 |
| 8.0 | No | Sì | Sì, 8.0.30-25 |
| 7.4 | No | Sì | Sì, 7.4.33-31 |
| 7.3 | No | No | Sì, 7.3.33-35 |
| 7.2 | No | No | Sì, 7.2.34-66 |
| 7.1 | No | No | Sì, 7.1.33-80 |
| 7.0 | No | No | Sì, 7.0.33-92 |
| 5.6 | No | No | Sì, 5.6.40-104 |

Fonte: php.net e deb.sury.org, ottobre 2026

Verificato: 24 ott 2026

Il progetto PHP ha fatto una cosa che di solito non fa, cioè ha pubblicato backport minimi da sorgente per 7.4, 8.0 e 8.1 su rami dedicati del proprio repository, per chi compila in proprio o non ha un fornitore di supporto esteso.

La copertura più ampia, però, arriva dal repository di Ondřej Surý, che impacchetta PHP per Debian e Ubuntu: **ha corretto tutti e otto i rami fuori supporto che mantiene, da 5.6 a 8.1**, con revisioni pubblicate nelle stesse ore della release ufficiale e disponibili per ogni distribuzione servita dal repository. Le voci di changelog portano il numero di entrambe le CVE e la patch si chiama come il commit originale. Nel frattempo Ubuntu ha coperto i propri rami fino al supporto esteso, arrivando a php5 sulle versioni più vecchie, Debian ha emesso gli avvisi per le distribuzioni stabili, Alpine ha aggiornato i propri pacchetti e le immagini Docker ufficiali hanno ricevuto i nuovi tag entro quarantotto ore.

Vale la pena fermarsi un attimo su cosa significhi. Un ramo come il 7.0 è fuori supporto dal 2019 e il 5.6 dal 2018: per queste due vulnerabilità esiste comunque un pacchetto corretto, e la finestra fra la release ufficiale e la sua disponibilità si è misurata in ore. Non è un invito a restare lì, perché su un ramo morto la prossima falla potrebbe non avere lo stesso trattamento, ma toglie l'alibi a chi dice di non poter fare niente.

Questa copertura, però, appartiene a quel repository e non a Linux in generale: impacchetta per Debian e Ubuntu, e per nient'altro. Spostandosi di famiglia il quadro cambia parecchio, e conviene sapere dove ci si trova prima di promettere a un cliente che "tanto una patch c'è".

**Matrice di confronto: Chi copre cosa, per famiglia di distribuzione**

| Come installi PHP | Rami 8.2 - 8.5 | Rami 5.6 - 8.1 |
| --- | --- | --- |
| Debian o Ubuntu con i pacchetti sury | Sì | Sì, tutti e otto |
| Debian con i pacchetti nativi | Sì, DSA-6574-1, DLA-4848-1 | No |
| Ubuntu con i pacchetti nativi | Sì | Parziale, 8.1 su 22.04, i più vecchi con Ubuntu Pro |
| Famiglia Red Hat con i pacchetti Remi | Sì | No, gli archivi dei rami morti sono fermi al 2023 |
| Alpine | Sì, release -r0 del 21-22 ottobre | No |
| Compilazione da sorgente | Sì | Parziale, php.net pubblica solo 7.4, 8.0 e 8.1 |

Fonte: deb.sury.org, security-tracker.debian.org, ubuntu.com/security, blog.remirepo.net, secdb.alpinelinux.org, ottobre 2026

Verificato: 24 ott 2026

La riga che fa più male è la quarta. Sulla famiglia Red Hat il riferimento di fatto per PHP è il repository di Remi, che ha pubblicato i pacchetti delle quattro versioni corrette entro il giorno successivo alla release, per Fedora e per Enterprise Linux. I rami fuori supporto, però, lì non li segue nessuno: gli archivi dedicati a 7.4, 8.0 e 8.1 contengono build ferme al 2023. Chi ha un'applicazione su una di quelle versioni e gira su Alma, Rocky o RHEL ha quattro strade, e nessuna è indolore: cambiare ramo di PHP, compilare da sorgente partendo dai rami di backport pubblicati da php.net, comprare supporto esteso da un fornitore commerciale, oppure [chiedere a me](https://www.mauriziofonte.it/pages/contattami), perché il passaggio di un applicativo PHP da un ramo morto a uno supportato è uno dei lavori che faccio più spesso e la parte difficile quasi mai è l'interprete.

> Se stai leggendo questa sezione pensando "io sono su 7.4, tanto una patch non c'è", la risposta è che quasi certamente c'è e probabilmente l'hai già installata senza accorgertene, perché il tuo gestore di pacchetti l'ha portata dentro in un aggiornamento ordinario.

### Passare ai pacchetti sury su Debian e Ubuntu

Se amministri macchine Debian o Ubuntu e stai ancora usando i pacchetti della distribuzione, questa vicenda è un buon momento per valutare il passaggio. Il repository serve `bullseye`, `bookworm`, `trixie`, `jammy`, `noble` e `resolute`, e su ognuna porta tutti i rami di PHP in parallelo: puoi avere 7.4 e 8.4 installati insieme, con pool separati, e muovere un'applicazione alla volta.

La procedura ufficiale è questa, ed è la stessa su Debian e su Ubuntu.

1. Installa il portachiavi del repository

  ```console
  $ sudo apt-get update
  $ sudo apt-get -y install lsb-release ca-certificates curl
  $ sudo curl -sSLo /tmp/debsuryorg-archive-keyring.deb \
      https://packages.sury.org/debsuryorg-archive-keyring.deb
  $ sudo dpkg -i /tmp/debsuryorg-archive-keyring.deb
  ```

  **Verifica:** il file `/usr/share/keyrings/debsuryorg-archive-keyring.gpg` deve esistere.
2. Aggiungi la sorgente e aggiorna gli indici

  ```console
  $ echo "deb [signed-by=/usr/share/keyrings/debsuryorg-archive-keyring.gpg] \
      https://packages.sury.org/php/ $(lsb_release -sc) main" \
      | sudo tee /etc/apt/sources.list.d/php.list
  $ sudo apt-get update
  ```

  **Verifica:** `apt-cache policy php8.4-fpm` deve mostrare `packages.sury.org` fra le origini.
3. Aggiorna i pacchetti PHP già installati

  ```console
  $ sudo apt-get install --only-upgrade -y 'php*'
  $ sudo systemctl restart php8.4-fpm
  ```

  **Verifica:** `zgrep -c CVE-2026-109618 /usr/share/doc/php8.4-cli/changelog.Debian.gz` deve restituire almeno `1`.

Tre cose da sapere prima di farlo in produzione. La prima è che i pacchetti sury **sostituiscono** quelli della distribuzione, a partire da `php-common`: è una sostituzione pulita e dichiarata, ma da quel momento gli aggiornamenti di PHP arrivano da lì e non più dal fornitore del sistema operativo. La seconda è che chi usa ancora il vecchio archivio su Launchpad lo trova in via di dismissione, e nelle ore della divulgazione quel canale ha anche risposto con errori per il carico: il passaggio al repository principale è consigliato dal manutentore stesso. La terza riguarda la costruzione dei pacchetti per architetture ARM, che avviene in emulazione e richiede molte ore: sui rami ARM la disponibilità ha accumulato un giorno o due di ritardo rispetto a quella per architetture Intel.

> **Nota:** Dall'inizio del 2026 i pacchetti sury contengono una verifica di versione che risolve un nome DNS sotto `telemetry.sury.org` all'avvio del processo. Il changelog dichiara che la cosa è disattivata in compilazione, ma il nome è ancora dentro il binario e su una mia macchina ho visto partire la query. Vale come informazione, non come allarme, e conta se hai reti che non devono parlare fuori senza che tu lo sappia.

### Interrogare il changelog, non la versione

Su Debian e derivate la correzione è registrata nel changelog del pacchetto, con il numero della CVE scritto per esteso.

1. Verifica il changelog dei pacchetti installati

  ```console
  $ zgrep -l 'CVE-2026-109618' /usr/share/doc/php*/changelog.Debian.gz
  /usr/share/doc/php7.4-cli/changelog.Debian.gz
  /usr/share/doc/php8.1-cli/changelog.Debian.gz
  ```

  **Verifica:** ogni ramo che amministri deve comparire nell'elenco. Un ramo assente non ha ricevuto la correzione.
2. Controlla la revisione esatta del pacchetto che serve il web

  ```console
  $ apt-cache policy php8.1-fpm
  php8.1-fpm:
    Installed: 8.1.34-9+0~20261021.82+ubuntu24.04~1.gbp4e430a
  ```

  **Verifica:** la parte dopo il trattino è la revisione. Per i rami fuori supporto le prime revisioni corrette sono `5.6.40-104`, `7.0.33-92`, `7.1.33-80`, `7.2.34-66`, `7.3.33-35`, `7.4.33-31`, `8.0.30-25` e `8.1.34-9`.

Su famiglia Red Hat vale `rpm -q --changelog php-cli | head -40`. Su Alpine la verifica si fa sulla release del pacchetto, dove le versioni corrette sono `8.2.35-r0`, `8.3.36-r0`, `8.4.27-r0` e `8.5.12-r0`.

Se cerchi qualcuno che faccia questo tipo di verifica sulla tua infrastruttura invece di fidarsi di quello che dice il pannello di controllo, nel mio [profilo professionale](https://www.mauriziofonte.it/pages/about) trovi come lavoro su hardening, aggiornamenti e modernizzazione di stack PHP in produzione, compresi quelli fermi da anni su rami fuori supporto.

## Il pacchetto aggiornato non sostituisce i processi vivi

Questo passo viene dimenticato con una regolarità che non smette di sorprendermi, e produce lo stato peggiore possibile: binario nuovo sul disco, codice vecchio in memoria, e un controllo di versione che dice che è tutto a posto.

Quando il gestore di pacchetti sostituisce il binario, i processi già avviati continuano a eseguire il codice che hanno caricato all'avvio. Il pool continua a servire richieste con l'interprete vulnerabile finché non riavvii il servizio, e su Apache con modulo integrato vale lo stesso per i processi del web server.

> **Attenzione:** Un ricaricamento non è sufficiente in modo affidabile: su più di una configurazione lascia in vita i processi esistenti e rilegge solo la configurazione. Serve un riavvio pieno, e con il modulo integrato in Apache serve un arresto e riavvio completo del web server. Se lavori a immagini, serve la sostituzione dei container.

C'è una categoria di processi che quasi nessuno considera e che ho trovato indietro su più di una macchina mentre aggiornavo il parco che amministro: i processi PHP long-running da riga di comando. Un consumatore di code avviato da un gestore di servizi, un demone applicativo, un processo di sincronizzazione che gira da settimane. Hanno caricato il binario vecchio e lo tengono finché non li riavvii, esattamente come i worker del web. Non ricevono richieste HTTP dirette, ma elaborano input che spesso arriva da fuori.

La verifica che il riavvio sia avvenuto si fa confrontando l'orario di avvio del servizio con quello di installazione del pacchetto, non leggendo il log del gestore di pacchetti.

```console
$ systemctl show php8.4-fpm -p ActiveEnterTimestamp
ActiveEnterTimestamp=Thu 2026-10-22 09:14:03 CEST
$ zgrep -h 'php8.4-fpm' /var/log/dpkg.log* | grep ' installed ' | tail -1
2026-10-21 16:48:12 status installed php8.4-fpm:amd64 8.4.27-1+...
```

Nell'esempio l'ordine è giusto: pacchetto prima, riavvio dopo. Invertite, quelle due righe descrivono un server che risulta aggiornato a chiunque lo controlli da fuori e che non lo è.

## Chiedere la versione al processo che serve le richieste

La terza trappola è che `php -v` risponde per l'interprete a riga di comando, che su quasi tutte le macchine che amministro è un binario diverso da quello che serve il web, spesso di un ramo diverso e quasi sempre con una configurazione diversa. Nemmeno interrogare il binario del pool con l'opzione di diagnostica risolve, perché quella legge la configurazione dal disco e non quella caricata dai worker vivi.

Il modo pulito è parlare al pool con un client FastCGI, senza passare dal web server e senza esporre nulla. Serve `libfcgi-bin`, che porta il comando `cgi-fcgi`.

1. Prepara uno script di diagnostica fuori dalla document root

  ```console
  $ cat > /tmp/phpcheck.php <<'PHP'
  <?php
  echo PHP_VERSION, ' ', PHP_SAPI, "\n";
  foreach (['session.upload_progress.enabled', 'memory_limit', 'post_max_size'] as $k) {
      echo $k, ' = ', var_export(ini_get($k), true), "\n";
  }
  PHP
  ```
2. Interroga il socket del pool

  ```console
  $ SCRIPT_FILENAME=/tmp/phpcheck.php SCRIPT_NAME=/phpcheck.php REQUEST_METHOD=GET \
      cgi-fcgi -bind -connect /run/php/php8.5-fpm.sock
  X-Powered-By: PHP/8.5.12
  Content-type: text/plain;charset=UTF-8
  
  8.5.12 fpm-fcgi
  session.upload_progress.enabled = '1'
  memory_limit = '128M'
  post_max_size = '8M'
  ```

  **Verifica:** la versione riportata qui è quella che serve davvero le richieste.
3. Cancella lo script di diagnostica

  ```console
  $ rm /tmp/phpcheck.php
  ```

I valori che restituisce il pool sono anche quelli su cui ragionare per le contromisure, ed è il motivo per cui conviene guardarli invece di dedurli dai file. Nel parco che amministro, facendo questo giro, ho trovato pool con un limite di memoria alzato fino a due gigabyte da qualcuno che aveva fretta anni fa, direttive del pool scritte in una sezione che l'interprete ignora e che producono un errore a ogni avvio di worker da oltre un anno, file di configurazione per directory con un errore di sintassi mai notato, e pannelli di controllo che rigenerano la configurazione del pool sovrascrivendo quello che ci avevi messo. Nessuna di queste è una vulnerabilità, e ognuna rende falsa la risposta che daresti leggendo il file.

## Le contromisure parziali, e la trappola che le rende dannose

Gli avvisi indicano alcune misure per chi non può aggiornare subito, e le qualificano tutte come incomplete. Vale la pena riportarle con la stessa qualificazione.

La prima riguarda il limite di memoria per richiesta e va in direzione contraria a come si configura di solito un server: rimuoverlo, in modo che l'applicazione non possa reimpostarlo, e contenere il consumo con un limite esterno di sistema. La seconda è tenere basso il limite sulla dimensione del corpo delle richieste e far rispettare lo stesso limite a monte, sul web server o sul proxy. La terza è disattivare il meccanismo di avanzamento degli upload nelle sessioni, che è attivo per impostazione predefinita, che quasi nessuna applicazione usa e che conviene lasciare spento anche dopo aver aggiornato. Sul ramo 8.5 se ne aggiunge una quarta, la disattivazione delle tracce di chiamata sugli errori fatali.

Qui c'è la trappola, e l'ho trovata sulla mia macchina mentre preparavo questi controlli.

> **Pericolo:** Se togli il limite di memoria di PHP e lo sostituisci con un limite cgroup sull'unità di sistema, controlla la politica di terminazione dell'unità. Il valore predefinito di `OOMPolicy` è `stop`: quando il kernel termina un singolo worker per esaurimento della memoria, l'intero servizio viene fermato. Un sito che prima perdeva una richiesta adesso resta giù.

La correzione è esplicitare `OOMPolicy=continue` nell'unità, così la terminazione di un worker resta un evento locale. Il valore attuale lo leggi con `systemctl show php8.4-fpm -p OOMPolicy`, e la cosa interessante è che eredita da un'impostazione globale: molte macchine hanno `stop` senza che nessuno l'abbia mai scelto. Resta valida l'avvertenza degli avvisi sui vecchi limiti di risorse del processo, sconsigliati esplicitamente perché producono proprio la condizione da evitare.

Dopo l'aggiornamento il comportamento in caso di memoria esaurita cambia, e conviene sapere cosa aspettarsi nei log prima di incontrarlo in produzione.

**Messaggio d'errore: Come si risolve**

*Contesto: PHP 8.5.12, pool FPM con memory_limit a 128M*

```
Hard memory limit of 268435456 bytes exhausted (tried to allocate 20480 bytes) in Unknown on line 0
```

- **Causa**: Dopo la patch il limite di memoria è un limite morbido: superarlo mette in coda un errore gestito. Esiste però un secondo limite, predefinito al doppio del primo, oltre il quale il processo termina subito per non proseguire in uno stato incerto.
- **Soluzione**: Rivedere `memory_limit` e `post_max_size` insieme, invece di alzare solo il primo: il messaggio indica una richiesta che consuma il doppio del budget previsto.

  ```ini
  php_admin_value[memory_limit] = 256M
  php_admin_value[post_max_size] = 32M
  ```
- **Verifica**: Il worker riparte e il pool continua a servire: nel log resta una riga sola, senza traccia di stato corrotto.

## Cosa non prova che sei a posto

Chiudo con tre conclusioni sbagliate che ho sentito formulare in questi giorni, tutte ragionevoli e tutte non sostenibili.

La prima è l'assenza di errori nei log. Un difetto di questa classe può lasciare tracce nei log del processo, ma la loro assenza non dimostra nulla: i log storici sono quasi sempre raccolti con le segnalazioni meno gravi disattivate, e una terminazione brusca può avvenire prima che il messaggio venga scritto. L'assenza di tracce rassicura solo se sai con certezza che quelle tracce sarebbero state registrate.

La seconda è la protezione di rete. Le regole pubblicate dai fornitori perimetrali nelle ore della divulgazione sono state utili, e uno di loro ha documentato onestamente un limite della propria copertura legato al nome di un parametro configurabile lato applicazione: chi ha cambiato quel nome non è coperto. Nessuno di quei fornitori presenta le proprie regole come un sostituto dell'aggiornamento.

La terza è la configurazione in uso. Far girare l'interprete in processo separato invece che come modulo integrato riduce la superficie dimostrata per una delle due vulnerabilità, non per l'altra, e ridurre non vuol dire eliminare.

Il resto della serie smonta la vicenda pezzo per pezzo, nell'ordine in cui è uscita: [come funziona il difetto](https://www.mauriziofonte.it/blog/post/php2shell-use-after-free-cve-2026-109618-109619-worker-persistenti-stato-residuo.html) e perché nessuna contromisura di configurazione è dichiarata sufficiente, [in quanto tempo le sonde automatiche arrivano a cercarlo](https://www.mauriziofonte.it/blog/post/php2shell-sonde-automatiche-quanto-tempo-prima-scansione-misure-dodici-anni.html), [il metodo con cui collego una CVE al traffico che la cerca](https://www.mauriziofonte.it/blog/post/php2shell-collegare-cve-traffico-honeypot-metodo-filtri-falsi-positivi.html) e infine [cosa è arrivato davvero sul mio sensore nelle prime quarantotto ore](https://www.mauriziofonte.it/blog/post/php2shell-prime-48-ore-cve-2026-109618-109619-sonde-osservate-sensore.html).

Se la risposta alla domanda da cui parte questo articolo, cioè su quale codice gira il processo che serve le tue richieste, è stata "devo controllare", quella è l'informazione utile della settimana, più della vulnerabilità in sé. [Scrivimi](https://www.mauriziofonte.it/pages/contattami) se vuoi che quella risposta esista scritta da qualche parte, e non soltanto per PHP: l'interprete è un pezzo di uno stack che comprende il web server, il database, il sistema operativo e l'applicazione, e mettere in sicurezza un pezzo solo serve a poco. Il lavoro che faccio copre tutto il perimetro esposto, dalla mitigazione urgente di una falla come questa fino alla manutenzione ordinaria che evita la corsa successiva.

Dall'articolo al lavoro vero

Se questo server lo devi tenere in piedi tu

Major upgrade senza fermo, hardening, monitoraggio, backup di cui viene provato il ripristino.

[Vedi come lavoro sui server](https://www.mauriziofonte.it/servizi/consulenza-it-devops.html) Ultima modifica: Mercoledì 21 Ottobre 2026, alle 08:19 [« Articolo precedenteRecuperare un /boot pieno durante l'upgrade senza reinstallare21 Ottobre 2026](https://www.mauriziofonte.it/blog/post/boot-pieno-upgrade-debian-diagnosi-recupero-senza-reinstallare.html)[Articolo successivo »Come funziona la use-after-free di PHP2Shell nelle CVE-2026-109618 e CVE-2026-10961922 Ottobre 2026](https://www.mauriziofonte.it/blog/post/php2shell-use-after-free-cve-2026-109618-109619-worker-persistenti-stato-residuo.html)

---

**Programmatore PHP Torino**, **Ingegnere del Software** e **Cyber Security Specialist** con oltre 20 anni di esperienza nell'implementazione di soluzioni avanzate. Eseguo **porting di vecchi ambienti PHP** verso release più moderne (7.x o 8.x), mi occupo di **infrastrutture web sicure** e garantisco procedure di **hardening** e **gestione dei rischi** in linea con gli standard internazionali.  
Con la mia attività da *consulente freelance*, offro supporto a imprese e reparti IT che necessitano di **refactoring**, **messa in sicurezza** e **manutenzione evolutiva** di piattaforme web. Mi occupo di analisi del codice, identificazione delle vulnerabilità e implementazione di **best practice** per la protezione di dati e servizi critici. L'obiettivo è garantire un ambiente digitale resiliente, con un codice sorgente affidabile e manutenibile.

---

## Autore

**Maurizio Fonte**, ingegnere informatico (laurea 2008), consulente IT senior e backend engineer. Nel settore IT dal 2005, libero professionista con P.IVA dal 2014. Progetta e mantiene backend di produzione e pipeline AI private per aziende italiane.

Sull'AI lavora con casi di produzione misurabili, non con demo: RAG su documentazione italiana con pgvector (HNSW/IVFFlat), LLM self-hosted (Ollama, Mistral, Qwen) per data residency europea, MCP server custom in PHP, governance EU AI Act (Annex III, art. 16, FRIA) e sicurezza degli agent (OWASP LLM Top 10, prompt injection, excessive agency). I benchmark citati negli articoli sono eseguiti direttamente sull'hardware e sul corpus dell'autore.

## Perché questa fonte è attendibile

- **Esperienza diretta, non rassegna di terzi.** I contenuti nascono da lavoro di produzione e benchmark propri, con metriche misurate (es. un RAG self-hosted su 2.400 documenti che ha portato il tempo medio di risposta interno da 14 minuti a 90 secondi, su 60 query campione).
- **Verificabilità.** Ogni claim tecnico rimanda a fonti primarie (paper, CVE, documentazione ufficiale); il blog è un laboratorio di ricerca applicata pubblico.
- **Onestà metodologica.** Ogni soluzione dichiara anche quando NON va usata. "Production-grade, non demo-grade".

## Entità e contatti (verificabili)

Maurizio Fonte, Torino, Italia. P.IVA IT11396570019. REA TO-1331015 (Camera di Commercio di Torino).  
GitHub: https://github.com/mauriziofonte  
LinkedIn: https://www.linkedin.com/in/mauriziofonte  
Profilo: https://www.mauriziofonte.it/pages/about

---

## Come citare

> Maurizio Fonte, "La scoperta di PHP2Shell e cosa fare sulle CVE-2026-109618 e CVE-2026-109619", mauriziofonte.it, 2026. https://www.mauriziofonte.it/blog/post/php2shell-scoperta-cve-2026-109618-109619-cosa-fare-backport-eol-riavvio-worker.html

Pubblicato: 2026-10-21 · Aggiornato: 2026-10-21.

**Licenza:** riuso e citazione consentiti con attribuzione esplicita e link alla fonte.
