Uno scudo a dithering verde, per la messa in sicurezza di un sito WordPress

Sito WordPress attaccato: come l'ho reso sicuro e più veloce in poche ore

Un avviso da Search Console, il sito bianco e la decisione di spegnere WordPress invece di ripararlo. Il racconto dell'intervento e cosa cambia con una build statica.

Davide Ruggeri

Davide Ruggeri

Oggi uno dei siti che gestisco è stato attaccato. Poche ore dopo era di nuovo online, senza database, senza PHP in esecuzione e più veloce di prima. Non perché sono stato bravo a ripararlo: perché ho tolto di mezzo la cosa che si era rotta.

L’attacco: un’email da Google Search Console e il sito bianco

L’avviso non è arrivato da un’email di Google Search Console: era stato aggiunto un utente alla proprietà. Non ero io.

Mi allarmo, apro il sito: pagina bianca.

Perché non ho indagato sulle cause dell’attacco

Non ho perso un secondo a capire chi fosse entrato, da dove e cosa stesse cercando di fare. L’analisi si fa con calma, su una copia congelata, quando il sito del cliente è già tornato a funzionare. Il mio unico pensiero è stato: devo intervenire subito.

La domanda operativa era una sola: qual è il pezzo che si è fatto bucare, e mi serve ancora?

Il punto debole: un’istanza WordPress dietro il proxy

La stack di questo cliente è quella che ho raccontato in Da WordPress a uno stack moderno: un server Node con SvelteKit davanti che intercetta ogni richiesta, e dietro l’installazione WordPress originale, che continua a servire le rotte create prima del mio intervento.

È un’architettura che funziona benissimo per migrare senza traumi. Ha però una caratteristica che è comodo dimenticare: finché l’origine resta accesa, resta accesa anche la sua superficie di attacco. PHP in esecuzione, un database, i plugin ereditati, una pagina di login raggiungibile. Il proxy sposta le rotte, non fa sparire quello che c’è dietro.

E quel dietro, ormai, non serviva quasi più a niente. Tutte le parti dinamiche le avevo già migrate su Brixter e SvelteKit: la parte proxata erano solo contenuti. Pagine che cambiano poche volte l’anno, servite da un’applicazione viva che gira ventiquattro ore al giorno per dire sempre le stesse cose.

Era da un po’ che meditavo sulla reale necessità di tenere WordPress acceso lì sotto. L’attacco mi ha tolto la scusa per rimandare.

Tre obiettivi, in quest’ordine

  1. Sistemare al volo l’attacco.
  2. Hardening: non voglio più quella superficie.
  3. Velocità massima.

La cosa interessante è che una sola mossa li soddisfa tutti e tre.

Da WordPress dinamico a build statica: cosa ho fatto

Ho ricostruito l’istanza WordPress in locale, generato l’export statico completo (contenuti, redirect, sitemap) e servito quell’output da un container che non fa altro che restituire file. Sul proxy è bastato ripuntare l’upstream: stesse rotte, stessi URL, stessa resa. Ho cambiato il motore, non la carrozzeria.

Cosa gira adesso su quel pezzo di sito: nessun PHP, nessun database, nessuna area di amministrazione, nessun plugin. File su disco, dietro un proxy che ho scritto io.

Cosa si guadagna con un sito WordPress statico

  • La superficie di attacco si riduce al web server. Non ci sono credenziali da indovinare né vulnerabilità di plugin da aspettare.
  • Il tempo di risposta è quello di leggere un file, che è il limite fisico del problema.
  • Il backup è una cartella, il ripristino è copiarla.
  • Non c’è più un database da aggiornare, monitorare e salvare per contenuti che non cambiano.

Cosa si perde, perché qualcosa si perde

Chi ti vende una soluzione senza controindicazioni sta vendendo, non spiegando.

Con lo statico spariscono anche le funzioni che vivevano nel runtime: i form vanno riportati su un endpoint esterno, la ricerca interna e i commenti vanno ripensati o eliminati, e ogni pubblicazione richiede un passaggio di rigenerazione invece di essere immediata. Se un sito ha bisogno di aree riservate, carrelli o contenuti che cambiano da soli, questa strada non fa per lui.

Il punto è che la maggior parte dei siti aziendali non ne ha bisogno. Hanno bisogno di essere veloci, di essere trovati e di non spegnersi.

Cosa fare dopo un attacco, anche se rimandi l’analisi

Rinunciare all’indagine sulle cause è una scelta legittima. Rinunciare a queste cose no, ed è la parte che di solito manca nei racconti di questo tipo:

  • Rimuovere subito l’account aggiunto in Search Console e passare in rassegna tutti gli utenti della proprietà. Un accesso agli strumenti per webmaster serve a manipolare l’indicizzazione, ed è un danno che sopravvive al ripristino del sito.
  • Rigenerare credenziali e chiavi, e controllare gli utenti amministratori rimasti nel database prima di archiviarlo.
  • Verificare l’export. Se generi lo statico da un’istanza compromessa, rischi di congelare nei file anche l’iniezione. Prima di pubblicare vanno cercati script esterni, iframe e link nascosti che nell’output non dovrebbero esserci.
  • Conservare una copia dell’istanza attaccata. Un’analisi rimandata è rimandata, non cancellata.

WordPress come static site builder: l’unico uso che accetto su un sito professionale

Non uso quasi mai WordPress per costruire siti professionali, e i motivi li ho scritti altrove. Questo però è uno dei rari casi in cui lo trovo accettabile, anzi sensato: WordPress come strumento di composizione dei contenuti, il cui prodotto finale è un insieme di file statici, e non come applicazione esposta al pubblico.

Rovesciato così, il rapporto costi benefici cambia. Ti tieni un editor che i clienti conoscono e un archivio di contenuti già scritti, e butti via la parte che genera i problemi: il runtime esposto, il database, i plugin che eseguono codice a ogni visita, gli aggiornamenti da inseguire per sempre.

Prima era una casa con dieci porte, ognuna con una serratura da mantenere. Adesso è un muro con una finestra sul mondo, e la finestra la controllo io.

Se hai un WordPress che ti preoccupa

Se ti stai chiedendo cosa succederebbe al tuo sito in una giornata come questa, raccontamelo. Ti dico quale parte del tuo sito ha davvero bisogno di essere un’applicazione viva e quale invece può diventare un file, con che tempi e cosa cambierebbe nei tempi di risposta.