In breve: per vietare l'esecuzione di PHP negli upload, stabilisca prima tutte le cartelle in cui PHP può scrivere e blocchi poi in ciascuna l'esecuzione di script nella configurazione del server, non tramite .htaccess. In Nginx il blocco deve agire prima del blocco PHP generale, in Apache va nel VirtualHost con AllowOverride None. security.limit_extensions = .php nel pool FPM e un test con un file innocuo completano il lavoro.
Perché proprio ora contano le cartelle di upload
Dopo una vulnerabilità critica come PHP2Shell, gli aggressori raramente vogliono eseguire codice una volta sola. Vogliono tornare, anche quando il server verrà poi aggiornato con la patch. La via più semplice è una web shell: un piccolo file PHP, collocato in una cartella scrivibile e poi richiamato tramite il browser.
Una patch non rimuove un file simile. Chi dal 20 ottobre 2026 era online senza patch dovrebbe quindi non solo aggiornare, ma anche verificare se da qualche parte ci siano nuovi file PHP e impedire in futuro che vengano eseguiti. Come interpretare i reperti lo descrive File PHP nella cartella di upload: interpretare correttamente i reperti.
Il blocco dell'esecuzione agisce sulla seconda condizione. Non impedisce che un file venga depositato, ma che il server lo tratti come programma.
Prima l'inventario: dove può scrivere PHP?
La maggior parte delle istruzioni cita solo la cartella di upload. Nella pratica un'applicazione PHP scrive in molti più punti. Ognuno di essi, se raggiungibile tramite il server web, richiede il blocco.
| Tipo di cartella | Contenuto tipico | Perché scrivibile |
|---|---|---|
| Upload, media | immagini, PDF, allegati | utenti e redazione caricano file |
| Cache | pagine generate, miniature | l'applicazione accelera la consegna |
| Temp, importazione, esportazione | file CSV, stati intermedi | interfacce e scambio di dati |
| Backup nel webroot | .zip, .sql |
le estensioni salvano «in loco» |
| Log nel webroot | log di errore e di debug | applicazioni configurate male |
Quali siano queste cartelle sul Suo server lo mostra una ricerca con i permessi dell'utente di runtime. Non modifica nulla:
# Tutte le cartelle sotto /var/www in cui l'utente PHP può scrivere
# (adattare l'utente: www-data, nginx, apache o utente proprio del pool)
sudo -u www-data find /var/www -type d -writable 2>/dev/null | sort
# Nelle cartelle ci sono già file PHP?
sudo -u www-data find /var/www -type d -writable -print0 2>/dev/null \
| xargs -0 -I{} find {} -maxdepth 1 -type f -iname "*.ph*" 2>/dev/null
Se la prima ricerca restituisce l'intero webroot, il codice del programma appartiene all'utente di runtime. Dovrebbe cambiarlo prima, come descrive la guida Permessi dei file sul server web. Altrimenti non esiste cartella che non andrebbe bloccata.
Vietare l'esecuzione di PHP negli upload: Nginx
In Nginx decide l'ordine. Secondo la documentazione di Nginx, le espressioni regolari vengono controllate nell'ordine del file di configurazione e vince la prima corrispondenza. Se il blocco generale location ~ \.php$ sta prima del Suo blocco, il file viene eseguito. Per lo stesso motivo non protegge una semplice location con prefisso senza ^~.
Sicura è un'espressione regolare per tutte le cartelle bloccate, posta prima del blocco PHP. Copre anche le estensioni usate di rado:
server {
# ... configurazione di base ...
# 1. Blocco per le cartelle scrivibili, DEVE stare prima del blocco PHP
location ~* ^/(uploads|media|cache|tmp|export)/.*\.(php\d?|phtml|phar|pht|phps)$ {
deny all;
}
# 2. Blocco PHP generale: passare solo file esistenti
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/seite1.sock;
}
}
Adatti i nomi delle cartelle al Suo inventario. Nelle applicazioni con un unico punto di ingresso la via della lista di consenso è ancora più forte; lo schema è in Configurare Nginx per PHP in sicurezza.
Apache e PHP-FPM: il blocco nel punto giusto
In Apache il blocco appartiene alla configurazione del server o al VirtualHost. Un .htaccess nella cartella di upload non è adatto, perché può modificarlo chiunque possa scrivervi. Per l'intero webroot vale quindi AllowOverride None. Secondo la documentazione di Apache, AllowOverride è consentito solo in blocchi <Directory> senza espressioni regolari; lo imposti quindi sul webroot e il blocco con <DirectoryMatch> sotto di esso:
<Directory /var/www/seite1/public>
AllowOverride None
Require all granted
</Directory>
<DirectoryMatch "^/var/www/seite1/public/(uploads|media|cache|tmp|export)/">
<FilesMatch "\.(php\d?|phtml|phar|pht|phps)$">
Require all denied
</FilesMatch>
</DirectoryMatch>
Se gira ancora mod_php, aggiunga nello stesso blocco php_admin_flag engine off. Con PHP-FPM agisce una seconda barriera nel pool: security.limit_extensions stabilisce quali estensioni FPM esegua in assoluto. Secondo il manuale PHP il valore predefinito è .php .phar; si raccomanda la limitazione a .php.
; nel pool, ad es. /etc/php/8.3/fpm/pool.d/seite1.conf
security.limit_extensions = .php
Testare con un file innocuo
Se il blocco funzioni lo mostra solo un test. Collochi per poco in ogni cartella bloccata un file che emette soltanto un testo, lo richiami tramite il dominio e poi lo cancelli.
- Verificare la configurazione:
nginx -toapachectl configtest, poi ricaricare. - Creare il file di prova, ad esempio
uploads/sperrtest.phpcon il contenuto<?php echo 'ausgefuehrt';. - Richiamarlo con
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/uploads/sperrtest.php. Ci si aspetta403. - Se compare invece
200e il testo «ausgefuehrt», il blocco non agisce. Verificare configurazione e ordine. - Cancellare il file di prova e ripetere il test per ogni cartella e ogni sito.
Se durante l'inventario trova già file PHP sconosciuti in cartelle scrivibili, non cancelli nulla in fretta. Metta prima al sicuro lo stato e i log, perché questi file sono elementi di prova. Come procedere poi lo descrive Riconoscere e rimuovere le web shell.
Come costruire in modo sicuro nel codice le funzioni di upload, con verifica del tipo e archiviazione fuori dal webroot, è spiegato nella guida Realizzare in modo sicuro gli upload di file in PHP.
Conclusione: scrivere sì, eseguire no
Il blocco dell'esecuzione nelle cartelle scrivibili è una delle misure singole più efficaci contro le backdoor permanenti. Costa poche righe di configurazione e non rompe nulla nelle applicazioni costruite bene. Contano tre cose: un inventario completo invece della sola ovvia cartella di upload, l'ordine giusto in Nginx o il livello giusto in Apache e un vero test con un file innocuo.
Integrato da proprietari separati per il codice del programma, security.limit_extensions nel pool e una ricerca regolare di nuovi file PHP, si crea una situazione in cui un file depositato è sì fastidioso, ma quasi inutilizzabile. Non sostituisce né l'aggiornamento né la ricerca delle tracce, ma toglie agli aggressori uno dei loro strumenti più importanti.
Come aiuta PHP SOS in concreto?
- Inventario: rileviamo tutte le cartelle scrivibili per sito e le verifichiamo alla ricerca di file PHP presenti.
- Impostare i blocchi: inseriamo i blocchi di esecuzione in Nginx, Apache e PHP-FPM, nell'ordine giusto e senza dipendenza da
.htaccess. - Testare: verifichiamo ogni blocco con un file innocuo e documentiamo il risultato.
- Bonificare: in caso di reperti ci occupiamo della conservazione delle tracce e della rimozione del malware.
Domande frequenti
Basta un .htaccess nella cartella di upload per vietare PHP?
Non in modo affidabile. Chi può scrivere nella cartella può anche modificare o sostituire il .htaccess. Il blocco appartiene alla configurazione del server o al VirtualHost, e per il webroot dovrebbe valere AllowOverride None.
Quali cartelle devo bloccare?
Tutte le cartelle in cui l'utente PHP può scrivere e che sono raggiungibili tramite il server web. Oltre alle cartelle di upload sono spesso directory di cache, temporanee, di importazione, di esportazione e di backup. Le individui con una ricerca eseguita come utente di runtime.
Il blocco rompe il mio sito?
Di norma no, perché nelle applicazioni ben costruite le cartelle di upload e di cache non contengono script richiamati direttamente. Alcune estensioni però vi collocano file PHP. Dopo il passaggio testi quindi le funzioni principali.
Il blocco protegge da PHP2Shell?
No. PHP2Shell è una vulnerabilità nell'interprete PHP che si chiude solo con l'aggiornamento e il riavvio di tutti i worker. Il blocco impedisce però che un file depositato venga poi richiamato tramite il browser e usato come backdoor permanente.