Apri un qualsiasi sito WordPress al mondo e aggiungi /readme.html all'URL. Nella stragrande maggioranza dei casi vedrai una pulita pagina HTML che annuncia orgogliosamente nell'header la versione esatta di WordPress. Lo stesso vale per /license.txt, che è leggermente meno specifico ma conferma comunque che il sito gira su WordPress e dà un'idea approssimativa di quanto recente sia l'installazione.
Entrambi i file sono forniti con il core di WordPress. Vengono ricreati a ogni aggiornamento. Nessuno dei due è necessario per il funzionamento del sito. L'unico pubblico che realisticamente servono sono gli scanner automatici che identificano i siti in base alla versione del core, in modo da poter abbinare il risultato a un elenco di vulnerabilità note. Questa guida spiega perché ciò conta in pratica e come bloccare i file in modo pulito su Apache, su nginx e su shared hosting dove hai meno controllo diretto.
Perché è importante che readme.html sia raggiungibile?
La risposta onesta è: di per sé non molto. Conoscere la versione di WordPress di un sito non è una vulnerabilità. La versione del core di WordPress non è un segreto, e un aggressore determinato può solitamente scoprirla comunque, ad esempio tramite meta tag generator, il parametro di versione sugli script e stili caricati, o tramite la struttura della risposta REST API.
Quello che cambia la situazione è il modo in cui l'exploitation oggi funziona su larga scala. Gli scanner di massa non scelgono un bersaglio e poi cercano bug. Scelgono un CVE, costruiscono un elenco di ogni dominio su Internet che esegue una versione interessata e sparano l'exploit sull'intero elenco. Il modo più economico per costruire quell'elenco è recuperare readme.html su milioni di domini in parallelo e analizzare la versione dall'header. Qualsiasi cosa che renda il sito invisibile a quel passaggio di filtro ti rimuove dall'elenco dei candidati prima che l'exploit vero e proprio venga mai eseguito.
Quindi rimuovere readme.html non rende il sito sicuro. Rimuove una delle impronte digitali più economiche, il che in pratica significa che non compari più negli elenchi automatici di "siti WordPress che eseguono la versione X.Y.Z". Vale alcuni minuti di lavoro, anche se non è l'hardening di sicurezza più critico che puoi eseguire.
E license.txt e gli altri file core?
Lo stesso tipo di file, leggermente meno interessante:
license.txtcontiene il testo della licenza GPL. Non contiene un numero di versione, ma la sua presenza nella root di WordPress è un forte segnale che il sito gira su WordPress.wp-config-sample.phpviene fornito con ogni installazione. Non contiene credenziali, ma rivela che nessuno ha fatto pulizia dopo la configurazione.readme.htmlè quello con il problema della divulgazione della versione.
La regola di blocco sottostante copre tutti e tre in una volta. Non c'è una buona ragione per lasciarne uno raggiungibile pubblicamente.
Opzione 1: bloccare tramite .htaccess (Apache e LiteSpeed)
Se il tuo host gira su Apache o LiteSpeed (che copre la maggior parte degli host condivisi nel mercato italiano: Aruba, SiteGround, Hostinger e la maggior parte dei reseller), puoi aggiungere il seguente blocco al file .htaccess nella tua cartella root di WordPress:
<FilesMatch "^(readme\.html|license\.txt|wp-config-sample\.php)$">
Require all denied
</FilesMatch>Lo snippet usa la sintassi di Apache 2.4, che è quello che ogni host esegue da anni. Se sei ancora bloccato su Apache 2.2 (estremamente raro nel 2026, ma possibile su hosting datato), usa la sintassi più vecchia:
<FilesMatch "^(readme\.html|license\.txt|wp-config-sample\.php)$">
Order allow,deny
Deny from all
</FilesMatch>Posiziona il blocco sopra il marker # BEGIN WordPress. Tutto tra # BEGIN WordPress e # END WordPress è gestito da WordPress stesso e viene riscritto quando i permalink cambiano o vengono eseguiti aggiornamenti del core. Tutto al di fuori di quei marker viene lasciato in pace.
Dopo aver salvato il file, apri https://tuodominio.it/readme.html in una finestra privata del tuo browser. Dovresti ottenere un 403 Forbidden. Lo stesso vale per /license.txt. Se vedi ancora il contenuto del file, il tuo host ignora .htaccess completamente (raro su Apache, normale su nginx) oppure ha AllowOverride impostato su un valore che rimuove le direttive FilesMatch. Vai all'Opzione 3.
Opzione 2: bloccare tramite nginx
Su nginx non c'è .htaccess. Se gestisci il tuo server (un VPS presso Hetzner, Netcup, DigitalOcean, o un host nginx gestito dove controlli la configurazione), aggiungi quanto segue all'interno del blocco server del tuo sito:
location ~* ^/(readme\.html|license\.txt|wp-config-sample\.php)$ {
deny all;
return 403;
}Ricarica nginx con sudo nginx -t && sudo systemctl reload nginx, poi testa con curl -I https://tuodominio.it/readme.html. La prima riga della risposta dovrebbe essere HTTP/2 403.
Diversi host WordPress gestiti che usano internamente nginx (Raidboxes, Kinsta, WP Engine, Cloudways) forniscono regole standard di questo tipo. Vale la pena consultare la documentazione dell'host. Se non lo fanno, il supporto solitamente aggiunge la regola per te su richiesta.
Opzione 3: shared hosting dove le sovrascritture .htaccess non funzionano
Alcuni shared host strettamente schermati eseguono nginx e ignorano completamente .htaccess. Altri eseguono Apache ma con regole AllowOverride restrittive. Se né l'Opzione 1 né l'Opzione 2 sono disponibili, hai tre alternative ragionevoli, ordinate per durata:
- Usa un plugin di sicurezza che gestisca l'hardening dei file core per te. Solid Security e All In One WP Security & Firewall hanno entrambi un interruttore "rimuovi file core" o "nascondi versione WordPress" che gestisce readme.html. Wordfence in modalità Extended Protection può anche bloccare i file a livello WAF. Il vantaggio è che queste impostazioni sopravvivono automaticamente agli aggiornamenti di WordPress.
- Svuota il file tramite un plugin Must Use. Se una regola a livello di server è impossibile, l'approccio più affidabile è un piccolo mu-plugin che sovrascrive readme.html e license.txt con contenuto vuoto dopo ogni aggiornamento di WordPress. Vedi l'articolo associato di snippet di codice nella nostra knowledge base.
- Elimina manualmente i file. La soluzione più rapida richiede dieci secondi tramite SFTP: elimina semplicemente
readme.html,license.txtewp-config-sample.phpdalla root di WordPress. Il problema è che gli aggiornamenti del core di WordPress ripristinano i file. Devi ricordarti di eliminarli di nuovo dopo ogni aggiornamento importante, ed è per questo che un plugin o una regola del webserver sono la migliore risposta a lungo termine.
Cosa non fare
Alcuni approcci che appaiono su vecchi post di blog, ma sono peggio di come sembrano:
- Rinominare i file. Rinominare
readme.htmlinreadme.html.oldsembra pulito, ma non aiuta. WordPress ricreerà semplicemente l'originale al prossimo aggiornamento, e ora hai due file invece di uno. - Impostare i permessi del file su 000. Questo blocca la lettura sulla maggior parte degli host, ma il prossimo aggiornamento del core resetta i permessi, e su alcuni host rompe anche l'upgrade stesso se WordPress non può leggere il file durante il processo di aggiornamento.
- Modificare i file per rimuovere il numero di versione. Allettante ma inutile. WordPress ripristina l'originale a un aggiornamento, e anche un readme.html modificato conferma comunque che il sito gira su WordPress.
Il pattern è lo stesso ogni volta: tutto ciò che si trova all'interno della cartella di installazione di WordPress e non è protetto da una regola del webserver viene resettato a un aggiornamento. Blocca a livello di webserver, o usa un plugin che sa come mantenersi attivo attraverso gli aggiornamenti.
Come verificare la tua configurazione
- Apri
https://tuodominio.it/readme.htmlin una finestra privata. Risultato atteso: una pagina403 Forbidden(o404se hai scelto l'eliminazione). - Stesso controllo per
https://tuodominio.it/license.txtehttps://tuodominio.it/wp-config-sample.php. - Se vedi ancora il contenuto del file, svuota le cache davanti al sito (Cloudflare, Varnish, cache delle pagine a livello di server come LiteSpeed Cache o WP Rocket) e riprova. Le risposte in cache possono nascondere la modifica per ore.
- Esegui una nuova scansione InspectWP. Il controllo per un readme.html esposto nella sezione sicurezza dovrebbe diventare verde.
Già che ci sei
Lo stesso tipo di regola FilesMatch o location vale la pena di applicarla ad alcuni altri endpoint che appaiono regolarmente nelle scansioni InspectWP: wp-config.php.bak, wp-config.php.swp, .git/, .env, phpinfo.php e qualsiasi info.php che uno sviluppatore ha lasciato durante il debugging. Stesso meccanismo, stesse cinque righe di configurazione, e rimuovi in una volta una classe intera di fingerprinting accidentale e perdite di credenziali.