La patch di WooCommerce Wholesale Lead Capture è uscita il 20 febbraio 2026. Gli attacchi più pesanti sono arrivati fra il 4 e il 17 giugno, con altri picchi il 1° luglio e il 30 agosto: il firewall di Wordfence ne ha bloccati più di 100.000, riporta BleepingComputer. Chi è stato colpito aveva la correzione disponibile da mesi e non l’aveva installata.
Il bersaglio era un file PHP caricato nella cartella dei media, poi richiamato dal browser come una pagina qualsiasi. È uno schema ricorrente negli attacchi via plugin, e si neutralizza con tre righe di configurazione che WordPress non mette da solo.
Come una cartella di immagini diventa una porta d’ingresso
La vulnerabilità, CVE-2026-27540, sta in un’azione AJAX del modulo di registrazione per i grossisti, wwlc_file_upload_handler, raggiungibile anche da chi non ha fatto login. Il controllo sulle estensioni ammesse esiste, ma secondo l’analisi di Wordfence ripresa da Infosecurity Magazine la lista viene letta dalla richiesta stessa invece che dalla configurazione del server. Basta aggiungere php alla lista e il plugin accetta un file eseguibile. In più la funzione di upload di WordPress viene chiamata con il controllo del tipo spento, quindi non resta nessun’altra barriera.
Il file caricato, spesso chiamato shell.php, è una webshell: raccoglie informazioni sul server e offre un modulo per scrivere altri file sul sito. Sono colpite tutte le versioni fino alla 2.0.3.1, su circa 6.000 installazioni attive. Il punto che interessa anche chi non usa questo plugin è un altro: il codice malevolo funziona solo perché il server accetta di eseguire PHP dentro wp-content/uploads. Se nessuno lo ha vietato in modo esplicito, il server lo fa.
Il blocco in due passaggi: prima cerca, poi chiudi
Prima di chiudere la porta controlla che nessuno sia già entrato. Dalla root del sito, via SSH, elenca i file eseguibili dentro la cartella dei media:
find wp-content/uploads -type f \( -iname '*.php' -o -iname '*.php[0-9]' -o -iname '*.phtml' -o -iname '*.phar' \) -ls
In una cartella che dovrebbe contenere immagini e PDF, ogni riga di questo output va spiegata. Un index.php vuoto messo da un plugin per impedire l’elenco dei file è normale; un file con un nome casuale e una data recente no.
Poi chiudi. Su Apache e su LiteSpeed Enterprise, che applicano le regole di accesso dei file .htaccess (OpenLiteSpeed da lì legge solo le rewrite: la regola va nella configurazione del virtual host), crea wp-content/uploads/.htaccess con questo contenuto:
<FilesMatch "(?i)\.(php[0-9]?|phtml|phar)$">
Require all denied
</FilesMatch>
La direttiva Require all denied è la sintassi di Apache 2.4. Su Nginx il file .htaccess viene ignorato e la regola va nel blocco server, prima della location generica che passa i file PHP all’interprete, perché tra le location con espressione regolare vince la prima che corrisponde:
location ~* ^/wp-content/uploads/.*\.(php|php[0-9]|phtml|phar)$ {
deny all;
}
Prova che la regola funziona, non fidarti della configurazione
Una regola scritta non è una regola applicata. Se l’hosting ha AllowOverride None, Apache ignora il tuo .htaccess in silenzio e il sito sembra protetto senza esserlo. Il test costa trenta secondi: crea un file innocuo, chiamalo dal browser o da terminale, poi cancellalo.
echo '<?php echo "eseguito";' > wp-content/uploads/test-lr.php
curl -s -o /dev/null -w '%{http_code}\n' https://www.example.com/wp-content/uploads/test-lr.php
rm wp-content/uploads/test-lr.php
Il risultato atteso è 403. Un 200 significa che il file è ancora raggiungibile (se il corpo della risposta contiene «eseguito», il PHP gira): la regola non viene letta, oppure sei su Nginx e la location sta dopo quella generica. Ripeti il test dopo ogni cambio di hosting o di stack, perché una migrazione riporta spesso la configurazione al default.
Se dopo la regola qualcosa smette di funzionare, hai trovato un plugin che esegue codice da una cartella di dati. È un’informazione più utile della funzione che si è rotta: chiedi allo sviluppatore perché lo fa prima di togliere il blocco.
L’errore da evitare: trattare il blocco come se fosse la patch
Le tre righe impediscono a un file caricato di girare. Non correggono il plugin: chi sfrutta il bug può ancora scrivere file, e un bypass di autenticazione non passa affatto dai media. Infosecurity Magazine lo dice anche per il firewall: la regola WAF ferma gli exploit noti, ma le versioni fino alla 2.0.3.1 restano vulnerabili sotto. Quindi l’ordine è fisso: aggiorna a 2.0.3.2 o successiva, poi blocca.
Se il primo passaggio ha trovato file sospetti, non basta cancellarli. Wordfence consiglia di cercare nei log le richieste ad admin-ajax.php con l’azione vulnerabile, rimuovere gli amministratori sconosciuti e controllare il sito alla ricerca di backdoor. Aggiunge che l’assenza di righe nei log non prova che il sito sia pulito. Una richiesta GET verso un file .php dentro /wp-content/uploads/, invece, nei log di accesso è un segnale da indagare subito, anche se le fonti non lo citano. Con la compromissione confermata, BleepingComputer riporta il consiglio di ripristinare da un backup sicuro, perché eliminare a mano ogni meccanismo di persistenza è difficile.
La mia take: la cartella dei media contiene dati, e i dati non devono essere eseguibili. È una delle poche difese che costano tre righe e tolgono l’esecuzione a un’intera classe di attacchi, non a un singolo CVE. Mettila nella checklist di consegna di ogni sito.
Altre letture sul tema: perché la patch va installata prima che arrivi il WAF e cosa espone davvero la libreria media via REST API.

