1 14/05/2026 12 min

Mettere in sicurezza un sito WordPress non significa installare un plugin e sperare che basti. Significa ridurre la superficie d’attacco, togliere privilegi inutili, osservare i log e avere un piano di rollback quando qualcosa rompe il sito. Se WordPress è esposto su Internet, devi considerarlo un servizio pubblico: l’obiettivo non è “chiuderlo del tutto”, ma renderlo costoso da compromettere e semplice da ripristinare.

La parte più importante è questa: gli attacchi contro WordPress raramente partono da una singola falla “epica”. Più spesso sfruttano combinazioni banali: credenziali deboli, plugin abbandonati, permessi file permissivi, upload esposti, XML-RPC lasciato aperto senza motivo, backup accessibili dal web, pannelli admin senza protezioni aggiuntive. La difesa va costruita a strati, non con un unico interruttore.

Parti dalla mappa del rischio, non dai plugin

Prima di toccare la configurazione, fai un inventario minimo. Devi sapere quali componenti hai davvero in produzione: versione di WordPress, tema attivo, plugin installati, PHP, web server, database, eventuale CDN/WAF, accesso SSH o pannello hosting, backup e sistema di monitoraggio. Senza questo elenco, ogni hardening è parziale.

Il controllo più semplice è anche il più utile: entra nel backend e annota cosa è installato. Poi incrocia con il filesystem e con il gestore pacchetti, perché non sempre quello che vedi in wp-admin coincide con lo stato reale sul server.

Esempio lato shell:

wp core version
wp plugin list
wp theme list
php -v
apachectl -v 2>/dev/null || nginx -v

Se non hai WP-CLI, usa almeno il pannello hosting per verificare versioni e stato dei componenti. Il punto non è lo strumento: è avere una fotografia precisa prima di cambiare qualcosa.

Riduci la superficie d’attacco pubblica

Il primo hardening serio è togliere tutto ciò che non serve esposto su Internet. In WordPress questo significa, in pratica: disabilitare o limitare XML-RPC se non usato, proteggere `wp-admin`, bloccare l’esecuzione di PHP nelle directory di upload, evitare directory listing, e non lasciare file sensibili raggiungibili dal web.

XML-RPC è spesso inutile nei siti moderni, ma resta attivo per compatibilità storica. Se non usi applicazioni esterne che richiedono quell’endpoint, puoi limitarlo a livello web server o WAF. Se invece ti serve, non bloccarlo alla cieca: prima verifica l’uso reale nei log.

Su Apache, una protezione comune per `wp-content/uploads` è impedire l’esecuzione di PHP. Il principio è semplice: i file caricati dagli utenti non devono diventare codice eseguibile.

<Directory "/var/www/example.com/wp-content/uploads">
    <FilesMatch "\.(php|phtml|phar)$">
        Require all denied
    </FilesMatch>
</Directory>

Su Nginx l’equivalente è bloccare l’esecuzione PHP nella directory di upload con una location dedicata. La regola precisa dipende dalla struttura del tuo vhost, ma il concetto resta identico: gli upload devono essere statici.

Verifica rapida dopo la modifica:

curl -I https://example.com/wp-content/uploads/test.php
curl -I https://example.com/xmlrpc.php

L’atteso è un 403 o un 404 per i file bloccati. Se vedi 200, la regola non è stata applicata nel punto giusto.

Gestisci gli aggiornamenti come una change, non come un click casuale

Molti compromessi arrivano da plugin o temi vecchi, non da WordPress core. Il problema non è solo aggiornare: è farlo in modo controllato. Un sito con decine di estensioni non va aggiornato “a caso” in orario di picco. Serve una routine: backup, finestra breve, verifica funzionale, rollback pronto.

La regola pratica è semplice: core, plugin e tema devono essere aggiornati con una frequenza legata al rischio, non al calendario del marketing. Se un plugin è fermo da mesi o anni, va trattato come componente sospetto. Se è critico e non mantenuto, la scelta corretta spesso è sostituirlo.

Con WP-CLI puoi controllare rapidamente quali componenti sono indietro:

wp core check-update
wp plugin list --update=available
wp theme list --update=available

Prima di aggiornare in produzione, fai almeno un backup database e file. Se il sito è su hosting con snapshot o backup automatici, verifica davvero che il restore sia possibile. Un backup che non hai mai ripristinato è solo una speranza con etichetta tecnica.

Credenziali: il vero perimetro di sicurezza

Se l’account admin cade, il resto dell’hardening conta molto meno. Per questo devi alzare il costo del brute force e del riuso credenziali. La base è banale ma non negoziabile: password lunghe e uniche, 2FA per gli account amministrativi, nomi utente non ovvi, limitazione dei tentativi di login e alert sui login sospetti.

Non usare plugin di sicurezza “a caso” per fare tutto insieme. Funzionano solo se sai cosa stai chiedendo loro. Alcune funzioni sono utili, ma altre possono introdurre falsi positivi o impattare il supporto agli utenti. Se vuoi limitare i tentativi di login, fallo con un plugin affidabile o, meglio ancora, con rate limiting lato reverse proxy o WAF.

Se hai accesso al server, puoi aggiungere protezione a `wp-login.php` con un controllo di accesso più stretto, oppure con restrizioni IP per gli ambienti amministrativi. Questa scelta ha senso solo se gli amministratori hanno IP relativamente stabili. Altrimenti rischi di bloccare operatività e assistenza.

Misura utile: controlla i log del web server per capire se stai ricevendo brute force massivi.

grep -E 'wp-login.php|xmlrpc.php' /var/log/nginx/access.log | tail -n 50
# oppure
grep -E 'wp-login.php|xmlrpc.php' /var/log/apache2/access.log | tail -n 50

Se vedi richieste ripetute da pochi IP o pattern automatizzati, alza il livello di protezione: rate limit, CAPTCHA solo dove serve, blocco a monte con WAF, o restrizione dell’accesso admin.

Permessi file e ownership: la falla silenziosa

Un WordPress con permessi troppo larghi è un invito al disastro. Il caso classico è il web server che può scrivere ovunque, oppure file configurati con `777` perché “così funziona”. No: così non funziona in sicurezza.

La regola pratica è: il processo web deve scrivere solo dove serve davvero, in genere `wp-content/uploads`, e in alcuni casi cache o directory temporanee. Il resto dovrebbe essere in sola lettura per l’utente del web server. L’ownership va pensata in base al modello operativo, non per abitudine.

Controllo rapido dei permessi:

find /var/www/example.com -type f -perm /o=w
find /var/www/example.com -type d -perm /o=w

Se trovi file o directory world-writable, indaga prima di correggere. Non cambiare alla cieca in produzione senza sapere quale processo li sta usando. Il rollback, in questo caso, è annotare lo stato iniziale e ripristinare ownership e mode solo dopo aver verificato il flusso applicativo.

In molti casi conviene mantenere il codice sotto un utente di deploy e far scrivere al web server solo su cartelle specifiche. Questo approccio riduce il danno di una compromissione applicativa: se un plugin viene sfruttato, l’attaccante non ottiene scrittura generalizzata su tutto il sito.

Hardening del file `wp-config.php` e dei segreti

Il file `wp-config.php` contiene informazioni ad alta sensibilità: credenziali database, sali di autenticazione, impostazioni di debug e spesso dettagli dell’ambiente. Non deve essere trattato come un file qualsiasi. Deve stare fuori dalla document root, se l’architettura lo consente, oppure essere protetto dal web server in modo esplicito.

Se hai accesso al server, valuta queste misure: disabilitare l’editing dei file da dashboard, forzare `DISALLOW_FILE_EDIT`, tenere il debug spento in produzione, e non pubblicare segreti nei repository. I sali e le chiavi di autenticazione vanno ruotati se sospetti una compromissione o se il file è stato esposto.

define('DISALLOW_FILE_EDIT', true);
define('WP_DEBUG', false);
define('WP_DEBUG_DISPLAY', false);

Non lasciare password in chiaro in ticket, note operative o screenshot. Se devi condividere configurazioni, redigi i valori sensibili e sostituiscili con placeholder coerenti. Se hai il sospetto che una credenziale sia finita in un posto non sicuro, la risposta corretta non è “speriamo”: è rotazione.

WAF, CDN e rate limiting: sicurezza a monte, non solo nel CMS

Molti attacchi si possono attenuare prima ancora che arrivino a WordPress. Un WAF o una CDN con protezione applicativa ti aiutano contro scansioni, exploit noti, bot e traffico anomalo. Non sostituiscono gli aggiornamenti, ma riducono il rumore e bloccano una parte degli attacchi commodity.

Qui la domanda giusta non è “quale prodotto è il migliore”, ma “quali regole mi servono davvero”. Inizia con pochi controlli: blocco delle richieste verso path noti di brute force, rate limit su login e XML-RPC, challenge ai bot sospetti, protezione contro upload malevoli, e alert sui picchi di 4xx/5xx.

Se usi Cloudflare o un WAF simile, controlla le metriche: numero di richieste mitigate, country/ASN anomali, path più colpiti. Se il tuo sito subisce scan continui, il WAF non risolve la causa, ma ti evita di consumare risorse dell’origin per traffico inutile.

Attenzione però a un errore comune: attivare regole troppo aggressive senza test. Un blocco sbagliato su `wp-admin/admin-ajax.php` o su endpoint di API legittimi può rompere funzionalità del tema, editor o plugin. Dopo ogni cambiamento, verifica checkout, form, login e caricamento media.

Backups: la sicurezza vera include il ripristino

Un sito sicuro è anche un sito ripristinabile. Se subisci una compromissione, il tempo di recupero conta quanto il perimetro. I backup devono coprire file, database e configurazioni esterne al CMS. Devono essere versionati, conservati off-site e testati con restore periodici.

Il test di restore è il punto che molti saltano. Invece va fatto davvero: ripristina in staging, verifica che il sito parta, controlla login, media, permalink, plugin critici e invio email. Se il restore fallisce, il backup non è un controllo di sicurezza: è un file conservato male.

Checklist minima:

  • backup giornaliero del database;
  • backup dei file modificabili e della configurazione del vhost;
  • copia off-site cifrata;
  • retention definita;
  • restore testato almeno su staging.

Se il backup contiene segreti, assicurati che sia protetto con cifratura e accessi limitati. Un archivio di backup accessibile da un bucket pubblico o da un account condiviso è un incidente in attesa di accadere.

Logging e audit: senza visibilità, la sicurezza è cieca

Devi sapere cosa succede quando qualcosa va storto. Al minimo, conserva log del web server, log PHP-FPM o PHP, log del database e audit degli accessi amministrativi. Se hai un sistema di centralizzazione, meglio ancora: ti permette di correlare tentativi di login, errori 5xx, picchi di CPU e modifiche ai plugin.

In WordPress, gli eventi più interessanti non sono solo gli errori. Sono anche i cambiamenti: installazione o disinstallazione di plugin, modifica di utenti admin, aggiornamenti, creazione di nuovi account, upload di file insoliti. Se hai un plugin di audit affidabile, usalo per tracciare questi eventi. Se non ce l’hai, almeno tieni i log di accesso e sistema in ordine.

Una verifica pratica utile è cercare pattern sospetti nei log:

grep -E 'POST .*wp-login.php|POST .*xmlrpc.php|/wp-admin/' /var/log/nginx/access.log | tail -n 100
journalctl -u php-fpm --since '24 hours ago' | tail -n 100

Se trovi errori PHP ricorrenti, non ignorarli. Un warning ripetuto può essere il segnale di un plugin rotto, di un path non scrivibile o di un attacco che sta forzando una zona specifica dell’applicazione.

Proteggi anche il livello di hosting e il pannello

La sicurezza di WordPress non finisce nel CMS. Se il pannello hosting è debole, se l’account FTP è condiviso, se SSH accetta password deboli o se il database è esposto sulla rete pubblica, hai già perso una parte del controllo. Il perimetro va chiuso dal basso.

Misure sensate: accesso SSH con chiavi, niente login root diretto, pannello amministrativo protetto da 2FA, database non esposto pubblicamente, firewall che accetta solo le porte necessarie, e separazione tra ambienti. Se usi cPanel, Plesk o simili, verifica che gli account abbiano privilegi minimi e che l’accesso admin sia tracciato.

Controllo rapido della superficie esposta:

ss -tulpn
ufw status verbose 2>/dev/null || firewall-cmd --list-all 2>/dev/null

Se trovi servizi non necessari in ascolto, la priorità è ridurre l’esposizione, non aggiungere un plugin di sicurezza al CMS. La sicurezza efficace parte dal server, poi sale all’applicazione.

Procedura pratica in 10 passi

Se devi mettere in sicurezza un sito WordPress già online, usa una sequenza ordinata. Non fare tutto insieme: cambia un livello, verifica, poi passa al successivo.

  1. Fai un backup completo di file e database e verifica che il restore sia possibile.
  2. Inventaria core, plugin, tema, PHP, web server e pannello hosting.
  3. Aggiorna WordPress core, poi plugin, poi tema, in finestra controllata.
  4. Disattiva o limita XML-RPC se non serve.
  5. Blocca l’esecuzione PHP in `wp-content/uploads`.
  6. Imposta `DISALLOW_FILE_EDIT` e disabilita il debug in produzione.
  7. Abilita 2FA per gli account admin e riduci i privilegi inutili.
  8. Verifica i permessi file e la scrivibilità delle sole directory necessarie.
  9. Aggiungi WAF o rate limiting su login e percorsi sensibili.
  10. Centralizza i log e configura alert su login anomali, 5xx e modifiche ai plugin.

Questa sequenza funziona perché parte dai controlli reversibili e ad alto impatto. Se qualcosa va storto, hai ancora il backup e un punto chiaro in cui fermarti.

Cosa non fare

Non affidarti solo a un plugin “security all-in-one” e non lasciarlo configurato con le opzioni di default. Non cambiare permessi a caso con comandi massivi senza sapere chi scrive dove. Non tenere credenziali nel codice sorgente. Non lasciare la dashboard accessibile senza protezioni aggiuntive se il sito è molto bersagliato. Non ignorare i log di errore perché “il sito sembra funzionare”.

Evita anche l’errore opposto: irrigidire tutto fino a rompere il sito. Se blocchi troppo `admin-ajax.php`, se imponi regole WAF aggressive o se togli scrittura dove un plugin la richiede, i primi a lamentarsene saranno gli utenti. La sicurezza utile è quella che resta compatibile con l’operatività.

Conclusione operativa: sicurezza sostenibile

Un WordPress ben difeso non è un WordPress “blindato” in senso assoluto. È un sistema dove l’attaccante incontra più ostacoli, lascia più tracce e trova meno punti deboli immediati. La differenza la fanno i fondamentali: aggiornamenti rapidi, privilegi minimi, backup veri, logging utile e protezione del perimetro.

Se vuoi un criterio semplice per capire se sei messo bene, chiediti questo: se domani un plugin critico viene sfruttato, quanto tempo mi serve per accorgermene e tornare online? Se la risposta non è chiara, la tua sicurezza è ancora incompleta. La buona notizia è che si può migliorare senza rifare tutto: basta lavorare per livelli, con verifiche dopo ogni passo.