In breve: memory_limit stabilisce quanta memoria può occupare una singola richiesta PHP; il valore predefinito è 128M. In esercizio normale imposti un valore finito adatto all'applicazione e lo blocchi con php_admin_value. Finché PHP2Shell non è corretto con una patch, php.net consiglia in via transitoria memory_limit=-1, non sovrascrivibile e combinato con un limite tramite container o cgroup, non tramite RLIMIT_AS o RLIMIT_DATA. Dopo l'aggiornamento torna a valere un valore finito.
Un'impostazione di routine che diventa all'improvviso un tema di sicurezza
Per anni memory_limit è stato una vite di regolazione per gli sviluppatori. Se un sito segnala «Allowed memory size exhausted», si aumenta il valore e il problema è risolto. Con PHP2Shell è diventato una questione di sicurezza, e la raccomandazione di php.net a prima vista sembra paradossale: per la fase transitoria il limite di memoria proprio di PHP dovrebbe cadere del tutto.
Lo sfondo è CVE-2026-109618. Secondo il progetto PHP, uno stato di out-of-memory può interrompere PHP mentre i dati della richiesta sono inizializzati solo in parte. La pulizia della richiesta può allora trattare come validi dati non validi. I dettagli tecnici sono in CVE-2026-109618; che cosa accade all'interno di PHP in caso di memoria insufficiente lo spiega memory_limit e out-of-memory. Per i gestori conta la domanda: quale valore vale quando, e dove deve essere impostato?
Che cosa fa memory_limit in esercizio normale
Secondo il manuale PHP, memory_limit limita la memoria che uno script può occupare e protegge così il server da codice scritto male. Il valore predefinito è 128M, -1 significa nessun limite. Sono consentite notazioni brevi come 256M o 1G.
Due proprietà sono importanti per la sicurezza. Primo, il valore è modificabile ovunque, anche in fase di esecuzione con ini_set(). Molti CMS e shop lo aumentano da soli, ad esempio per importazioni o elaborazione di immagini. Chi vuole imporre un valore deve impostarlo con php_admin_value; secondo il manuale, i valori così impostati non si possono sovrascrivere con ini_set(). Secondo, il manuale raccomanda che memory_limit sia maggiore di post_max_size.
Quale valore sia adatto dipende dall'applicazione. Uno sguardo al log degli errori mostra se compaiono messaggi di memoria esaurita e in quali chiamate. Si è dimostrato valido definire il valore per sito nel pool FPM proprio: più generoso per uno shop con importazioni, più contenuto per un semplice sito aziendale. Un valore indiscriminatamente molto alto per tutti i siti spreca l'effetto protettivo, perché allora una singola richiesta difettosa o abusata può occupare molta memoria.
Da PHP 8.5 esiste inoltre max_memory_limit. Questa impostazione può essere definita solo all'avvio e limita fino a che valore si possa impostare memory_limit. I valori più alti vengono ridotti con un avviso. Il valore predefinito -1 significa nessun limite superiore.
memory_limit dopo PHP2Shell: la misura transitoria di php.net
Per i server non ancora aggiornati a 8.5.12, 8.4.27, 8.3.36 o 8.2.35 o a un backport confermato, php.net nell'avviso di sicurezza del 21/10/2026 indica i passi seguenti. Riducono il rischio di singole vie di attacco, ma secondo php.net non rendono sicura un'installazione:
- Impostare
memory_limit=-1, possibilmente in modo che le applicazioni non possano sovrascrivere il valore, ad esempio conphp_admin_valuenel pool FPM o nella configurazione di Apache. - Verificare che da nessuna parte venga di nuovo impostato un limite finito, né in un altro pool, né in una configurazione di directory, né nell'applicazione.
- Impostare un limite di memoria tramite container o cgroup, a protezione della disponibilità, possibilmente in modo che in caso di superamento venga terminato solo il worker interessato.
- Non usare
RLIMIT_ASoRLIMIT_DATA. Secondo php.net questi limiti possono innescare proprio l'errore vulnerabile nella richiesta di memoria.
php.net spiega in proposito che -1 elimina il raggiungimento innescabile in modo mirato del limite di memoria di PHP, ma che un errore di memoria a un livello più profondo può comunque raggiungere il percorso vulnerabile. Il prospetto di tutte le misure transitorie è in Misure immediate se non può ancora applicare la patch.
; Pool FPM, ad es. /etc/php/8.3/fpm/pool.d/www.conf (solo fino all'aggiornamento)
php_admin_value[memory_limit] = -1
# Dove viene impostato memory_limit (solo lettura)
grep -rn 'memory_limit' /etc/php/ /etc/apache2/ 2>/dev/null
grep -rn --include='*.php' -E "ini_set\s*\(\s*['\"]memory_limit" /var/www | head -20
grep -rn --include='.user.ini' 'memory_limit' /var/www
Come impostare il limite cgroup per il servizio FPM lo descrive Impostare limiti di memoria con systemd e cgroup. Senza questo limite esterno, una singola richiesta può mettere l'intero server in carenza di memoria.
Dopo ogni modifica riavvii tutti i worker PHP. Un worker in esecuzione mantiene i vecchi valori.
Che cosa vale dopo l'aggiornamento
Con le versioni corrette, secondo il manuale PHP è cambiato anche il comportamento di memory_limit. Da 8.5.12, 8.4.27, 8.3.36 e 8.2.35 è un limite morbido: una richiesta di memoria che lo supera può, nella maggior parte dei casi, essere ancora completata prima che venga innescato l'errore. Una nuova impostazione, memory_hard_limit_percent, definisce un limite rigido che non viene mai superato.
| Impostazione | Valore | Effetto secondo il manuale |
|---|---|---|
memory_hard_limit_percent non impostato o -1 |
predefinito | limite rigido doppio rispetto a memory_limit fino a 1G, oltre memory_limit più 1G |
memory_hard_limit_percent = 150 |
esempio | con memory_limit=128M limite rigido di 192M |
memory_limit = -1 |
nessun limite | allora non c'è nemmeno un limite rigido |
Il manuale indica un punto di verifica pratico: se memory_hard_limit_percent non viene riconosciuto, la versione di PHP in uso è interessata e va aggiornata. Per i backport delle distribuzioni verifichi inoltre lo stato tramite il changelog del pacchetto.
# Il binario FPM conosce la nuova impostazione? (adattare il numero di versione)
php-fpm8.3 -i | grep -E 'memory_hard_limit_percent|memory_limit'
Dopo l'aggiornamento memory_limit=-1 ha assolto il suo scopo. Torni a un valore finito adatto all'applicazione e lo blocchi con php_admin_value. Il limite cgroup può restare come ulteriore livello di protezione.
Come aiuta PHP SOS in concreto?
- Stabiliamo dove sul Suo server
memory_limitviene impostato e sovrascritto, comprese le applicazioni. - Attuiamo le misure transitorie di php.net nel punto giusto e aggiungiamo un limite cgroup per il servizio FPM.
- Tramite il servizio di patch PHP portiamo PHP a una versione corretta e riavviamo tutti i worker.
- Poi reimpostiamo un valore finito adatto e documentiamo le impostazioni.
Domande frequenti
Qual è il valore predefinito di memory_limit?
Secondo il manuale PHP, 128M. Il valore limita quanta memoria può occupare un singolo script. Si può modificare in php.ini, nella configurazione del server, nel pool FPM e in fase di esecuzione con ini_set(), a meno che non sia bloccato con php_admin_value.
Perché php.net con PHP2Shell consiglia memory_limit=-1?
Una delle vulnerabilità, CVE-2026-109618, è legata allo stato in caso di memoria insufficiente. Secondo php.net, memory_limit=-1 elimina il raggiungimento innescabile in modo mirato del limite di memoria di PHP, ma non ogni errore di memoria. La misura non è una protezione completa e va combinata con un limite di memoria tramite container o cgroup.
Posso invece impostare il limite con ulimit?
No. php.net sconsiglia espressamente di usare RLIMIT_AS o RLIMIT_DATA come sostituto, perché questi limiti possono innescare proprio l'errore vulnerabile nella richiesta di memoria. Si raccomanda un limite tramite container o cgroup.
Che cosa vale dopo l'aggiornamento a una versione di PHP corretta?
Secondo il manuale, nelle versioni corrette memory_limit è un limite morbido, integrato da un limite rigido tramite memory_hard_limit_percent. La misura transitoria con -1 ha allora assolto il suo scopo e dovrebbe tornare a valere un valore finito, adatto all'applicazione.