Il mio sito WordPress è stato hackerato: cosa fare nelle prime due ore

Sito WordPress hackerato? Cosa fare subito: copia forense di file, database e log, manutenzione, credenziali da cambiare nell’ordine giusto, errori da evitare.

Una finestra del browser con un avviso rosso di sito compromesso accanto a un cronometro di due ore diviso in quattro fasi colorate

Il telefono squilla, un cliente scrive che il sito apre una pagina di scommesse, Google mostra un avviso rosso al posto dei risultati, oppure l’hosting manda una mail secca: account sospeso per invio di spam. Qualunque sia il segnale, la sensazione è la stessa, e la tentazione è una sola: entrare subito nel pannello, cancellare tutto ciò che sembra strano e far sparire il problema il prima possibile.

È la reazione più comprensibile e quasi sempre la più dannosa. Le prime due ore dopo la scoperta di un’infezione decidono se la pulizia sarà rapida e definitiva o se si trasformerà in una serie di reinfezioni senza una causa chiara. In questo articolo mettiamo in ordine le azioni da fare, quelle da evitare e il momento in cui conviene passare la mano a chi fa questo lavoro ogni giorno.

Linea del tempo delle prime due ore dopo la scoperta di un sito WordPress compromesso, divisa in quattro fasi: nei primi quindici minuti si osserva e si annota senza cancellare nulla; fino a quarantacinque minuti si fa la copia forense di file, database e log; fino a settantacinque minuti si decide se contenere il sito con una pagina di manutenzione o un blocco per indirizzo IP; fino a centoventi minuti si cambiano le credenziali partendo da quelle esterne al server
Le prime due ore in quattro fasi: prima si osserva e si conserva, poi si contiene, infine si chiudono gli accessi.

I primi quindici minuti: fermarsi e osservare

Il sito è già compromesso: qualche minuto in più non cambia la gravità dell’incidente, mentre un’azione sbagliata può cancellare proprio le tracce che servono a capire da dove è entrato l’attacco. Il primo compito è descrivere il problema con precisione, prima di modificare qualsiasi cosa.

Conviene aprire un file di testo e annotare, con data e ora:

  • come ci si è accorti del problema, e chi l’ha segnalato;
  • cosa si vede esattamente, e in quali condizioni: da computer o da smartphone, da utente collegato o anonimo, arrivando da Google o digitando l’indirizzo. Molte infezioni mostrano il contenuto malevolo solo ad alcuni visitatori, come spieghiamo nell’articolo sui redirect condizionali;
  • gli indirizzi delle pagine coinvolte e gli eventuali domini verso cui avviene il reindirizzamento;
  • i messaggi ricevuti da hosting, Google Search Console, clienti o circuiti di pagamento, conservati integralmente.

Qualche schermata, l’elenco delle pagine anomale restituite da una ricerca site: su Google e l’orario della prima segnalazione sembrano dettagli, ma diventano preziosi quando si tratta di stabilire la finestra temporale dell’attacco e di dimostrare, più avanti, che il problema è stato risolto.

La copia forense, prima di toccare qualsiasi cosa

Il passo che quasi tutti saltano è anche quello più importante: fare una copia completa dello stato attuale del sito, infezione compresa. Non è un backup da ripristinare, ma una fotografia da analizzare. Senza di essa, ogni file cancellato in fretta è un indizio perso, e se la pulizia non va a buon fine non resta nulla su cui ragionare.

Una copia utile comprende tre cose: i file del sito, il database e i log del server. Se si dispone di un accesso SSH, bastano pochi comandi, da eseguire in una cartella che non sia raggiungibile dal web:

# Cartella di lavoro fuori dalla document root
mkdir -p ~/incidente-2026-09-02 && cd ~/incidente-2026-09-02

# Elenco completo dei file con data di modifica (mtime), di cambio stato (ctime),
# proprietario e permessi: va fatto per primo, perché copiare i file non conserva il ctime
find /var/www/esempio.it/public_html -printf '%T+ %C+ %u %m %s %p\n' | sort > elenco-file.txt

# Archivio dei file, con permessi, proprietari e date di modifica originali
tar --numeric-owner -cpzf file-sito.tar.gz -C /var/www/esempio.it public_html

# Database completo, compresi trigger, procedure ed eventi pianificati
mysqldump --single-transaction --routines --triggers --events \
  -u utente_db -p nome_db > database.sql

# Impronte, per dimostrare in seguito che la copia non è stata alterata
sha256sum elenco-file.txt file-sito.tar.gz database.sql > SHA256SUMS

Per il database è preferibile mysqldump a wp db export: WP-CLI carica WordPress e quindi anche il codice dei plugin e del tema, cioè potenzialmente il malware stesso. Se si usa WP-CLI su un sito compromesso, conviene sempre aggiungere --skip-plugins --skip-themes. Le opzioni --routines e --events non sono attive di default e servono a non perdere eventuali trigger e procedure SQL malevoli.

Ai file e al database vanno aggiunti i log e lo stato del sistema, che sono volatili: i log vengono ruotati e cancellati dopo pochi giorni, i processi in esecuzione spariscono al primo riavvio.

# Log del server web e di PHP (i percorsi variano da server a server)
cp -a /var/log/nginx /var/log/apache2 /var/log/php*-fpm.log . 2>/dev/null

# Attività pianificate e processi dell'utente del sito
crontab -l > crontab.txt 2>&1
ps -u "$(id -un)" -o pid,lstart,args > processi.txt

# Chiavi SSH autorizzate sull'account
cp -a ~/.ssh/authorized_keys . 2>/dev/null

Su un hosting condiviso senza SSH si può ottenere lo stesso risultato dal pannello: il backup completo dell’account (su cPanel, per esempio, include file, database e configurazioni), il download dei log di accesso dalla sezione dedicata e un export del database da phpMyAdmin con l’opzione per includere trigger e routine. Una volta scaricata, la copia va conservata offline, fuori dal server compromesso.

Schema della copia forense di un sito WordPress compromesso: tre blocchi principali, cioè file con elenco delle date di modifica e di cambio stato, database esportato con trigger routine ed eventi, e log di accesso, errori e PHP-FPM; un quarto blocco con lo stato volatile del sistema, cioè crontab, processi attivi e chiavi SSH; tutto confluisce in un archivio con impronte SHA-256 conservato offline
Cosa entra nella copia forense: file, database e log, più lo stato volatile del sistema, che al primo riavvio va perso.

Tenere il sito online o metterlo offline?

Non esiste una risposta valida sempre. Dipende da cosa fa il malware e da chi ne subisce le conseguenze. Un sito vetrina che ospita pagine di spam in giapponese danneggia soprattutto il proprio posizionamento; un negozio con uno skimmer nella pagina di pagamento sta sottraendo i dati delle carte dei clienti a ogni ordine. Nel secondo caso il checkout va fermato subito, anche a costo di perdere vendite.

In generale conviene mettere il sito in manutenzione quando espone i visitatori a un danno diretto: furto di dati, download di file malevoli, pagine di phishing, redirect verso truffe. Si può invece tenerlo online, per il tempo strettamente necessario, quando l’infezione è limitata a contenuti di spam e fermarlo avrebbe costi sproporzionati, sapendo che ogni ora in più allunga la lista dei danni da riparare.

Il modo di metterlo in manutenzione conta. Un plugin di manutenzione gira dentro WordPress, cioè dentro l’applicazione compromessa, e il codice malevolo caricato prima di lui può continuare a funzionare. È più affidabile agire a livello di server web, lasciando accesso solo al proprio indirizzo IP e restituendo agli altri un codice 503, che i motori di ricerca interpretano come indisponibilità temporanea:

# NGINX, nel blocco server del sito
location / {
    if ($remote_addr != 203.0.113.10) { return 503; }
    try_files $uri $uri/ /index.php?$args;
}

# Apache 2.4, in cima al .htaccess della document root
RewriteEngine On
RewriteCond %{REMOTE_ADDR} !^203\.0\.113\.10$
RewriteRule ^ - [R=503,L]

Una pagina statica di cortesia servita con il 503 è sufficiente. Un fermo di qualche ora o di pochi giorni non compromette l’indicizzazione, mentre continuare a servire contenuti malevoli può portare all’inserimento in una blacklist, da cui uscire richiede una procedura a parte, descritta nell’articolo sulla rimozione dalle blacklist di Google.

Cambiare le credenziali nell’ordine giusto

Tutte le password vanno cambiate, questo è noto. Meno noto è che l’ordine conta. Se si cambia la password del database mentre nel sito c’è ancora una backdoor attiva, chi attacca può leggere la nuova password da wp-config.php un istante dopo. Se si cambia la password di WordPress ma non quella della casella di posta usata per il recupero, basta una richiesta di reset per rientrare.

Il criterio è partire dalle credenziali che controllano le altre e che vivono fuori dal server compromesso, e arrivare a quelle che stanno dentro il sito:

  1. la casella di posta associata all’hosting, al registrar del dominio e all’amministratore di WordPress, da un dispositivo pulito e con l’autenticazione a due fattori;
  2. il pannello dell’hosting e del registrar, anche questi con il secondo fattore, verificando gli utenti autorizzati;
  3. gli accessi al server: SSH, SFTP e FTP, rimuovendo le chiavi SSH che non si riconoscono e gli account FTP creati da altri;
  4. il database, aggiornando subito dopo DB_PASSWORD in wp-config.php;
  5. le chiavi e i salt di WordPress, che invalidano tutte le sessioni aperte, comprese quelle di chi attacca;
  6. gli utenti di WordPress, a partire dagli amministratori, eliminando quelli sconosciuti;
  7. le chiavi di servizi esterni: gateway di pagamento, SMTP, API, CDN, servizi di backup.

Le prime tre voci si possono cambiare in modo definitivo subito, perché non sono leggibili dal sito. Le altre stanno dentro il server: vanno cambiate adesso, per interrompere le sessioni in corso, e di nuovo alla fine della pulizia, quando si ha la certezza che nessuna backdoor possa leggerle.

# Nuova password del database (da MySQL o MariaDB, come amministratore)
ALTER USER 'utente_db'@'localhost' IDENTIFIED BY 'nuova-password-lunga-e-casuale';

# Aggiornamento di wp-config.php, senza caricare plugin e tema
wp config set DB_PASSWORD 'nuova-password-lunga-e-casuale' --skip-plugins --skip-themes

# Nuove chiavi e nuovi salt: tutte le sessioni esistenti vengono chiuse
wp config shuffle-salts --skip-plugins --skip-themes

# Amministratori presenti, con data di registrazione
wp user list --role=administrator --fields=ID,user_login,user_email,user_registered \
  --skip-plugins --skip-themes

Un amministratore che non si riconosce è un indizio da documentare prima di eliminarlo: la data di registrazione aiuta a datare l’attacco. Nell’articolo sugli amministratori fantasma spieghiamo come trovare anche quelli nascosti dall’elenco utenti.

Diagramma dell’ordine in cui cambiare le credenziali dopo un attacco a WordPress: a sinistra le credenziali esterne al server, cioè casella email, pannello di hosting e registrar, accessi SSH SFTP e FTP, da cambiare subito e in modo definitivo; a destra le credenziali interne al server, cioè password del database, chiavi e salt di WordPress, utenti amministratori e chiavi di servizi esterni, da cambiare subito e di nuovo dopo la pulizia
Si parte dalle credenziali che controllano le altre e che il sito non può leggere; quelle salvate sul server vanno cambiate due volte.

Controllare l’account di hosting, non solo WordPress

Un attacco che ha ottenuto l’esecuzione di codice sul sito ha, nella maggior parte dei casi, gli stessi permessi dell’utente di sistema che lo fa girare. Su un hosting condiviso quell’utente vede spesso tutti i siti dell’account: il blog dimenticato in una sottocartella, l’installazione di prova, il vecchio dominio mai cancellato. Ripulire un sito e lasciare infetto quello accanto significa ritrovarsi con lo stesso problema dopo pochi giorni.

Oltre ai siti, nel pannello dell’hosting vanno controllati:

  • le attività pianificate dell’account, uno dei posti preferiti per la persistenza, come raccontiamo nell’articolo sulle backdoor nei cron job;
  • gli account FTP e le chiavi SSH aggiunti di recente;
  • le caselle email e gli inoltri, usati a volte per inviare spam o per intercettare i reset di password;
  • i record DNS e i sottodomini, che possono essere stati aggiunti per ospitare pagine di phishing sotto il nome del dominio;
  • i file di configurazione di PHP a livello di account, come .user.ini o php.ini personalizzati, dove la direttiva auto_prepend_file può caricare codice malevolo prima di ogni pagina.

Se il server è dedicato o una VPS, il perimetro si allarga: processi in esecuzione che non hanno più un file su disco, come spieghiamo nell’articolo sui processi PHP in memoria, servizi in ascolto su porte insolite, utenti di sistema nuovi. In questo caso conviene anche avvisare subito il fornitore, che può avere visibilità su traffico e allarmi che dall’interno non si vedono.

Cosa non fare

Alcuni errori ricorrono in quasi tutti i siti che ci arrivano dopo un primo tentativo di pulizia fai da te. Non sono errori di incompetenza: sono le mosse che sembrano ragionevoli sotto pressione.

  • Cancellare i file sospetti uno per uno. Si eliminano gli effetti visibili e le prove, mentre la backdoor che li ha creati resta al suo posto.
  • Ripristinare subito l’ultimo backup. Se non si sa quando è iniziata l’infezione, non si sa se il backup è pulito; e anche se lo fosse, la vulnerabilità da cui è entrato l’attacco è ancora lì.
  • Aggiornare tutto e considerare chiuso il problema. L’aggiornamento corregge la vulnerabilità, ma non rimuove le backdoor già installate, che non dipendono più da quella falla.
  • Installare tre plugin di sicurezza diversi. Girano dentro l’applicazione compromessa e vedono solo una parte del problema, per ragioni che approfondiamo nell’articolo sui limiti degli scanner.
  • Chiedere subito la revisione a Google. Una richiesta respinta perché il sito è ancora infetto allunga i tempi della successiva.
  • Contattare chi attacca o pagare un riscatto. Non dà alcuna garanzia e segnala che il sito ha un gestore disposto a pagare.

Ogni file cancellato prima di aver capito come è arrivato è una domanda a cui non si potrà più rispondere.

Se sono coinvolti dati personali

Un sito con area riservata, moduli di contatto, iscrizioni alla newsletter o un negozio online tratta dati personali. Se l’attacco può averli esposti, si tratta di una violazione dei dati personali ai sensi del GDPR, e l’articolo 33 del Regolamento prevede che il titolare la notifichi all’autorità di controllo, in Italia il Garante per la protezione dei dati personali, entro 72 ore dal momento in cui ne è venuto a conoscenza, salvo che sia improbabile che presenti un rischio per le persone coinvolte.

Le prime due ore sono il momento giusto per avvisare chi si occupa della protezione dei dati in azienda e, se c’è, il consulente legale. Non serve avere già tutte le risposte: la valutazione del rischio si costruisce proprio sulle informazioni raccolte nella copia forense. È un’altra buona ragione per non cancellare le prove, e per annotare con cura i tempi della scoperta. Se sul sito passano pagamenti con carta, anche il fornitore del servizio di pagamento va informato, perché ha procedure proprie per questi casi.

Quando chiamare uno specialista

Molti incidenti semplici si possono gestire in autonomia, con metodo e con una copia di riserva a disposizione. Alcuni segnali, però, indicano che il problema va oltre i file di WordPress e che serve qualcuno abituato a guardare anche il sistema:

  • l’infezione torna dopo la pulizia, spesso alla stessa ora;
  • ci sono file illeggibili o codificati di cui non si conosce l’origine;
  • il sito tratta pagamenti o dati sensibili;
  • sullo stesso account o server ci sono molti siti;
  • non si ha accesso ai log o alla riga di comando, e quindi non si può ricostruire il vettore d’attacco.

Chi arriva da noi con una copia forense fatta bene fa risparmiare tempo a entrambi: i log dicono da dove è entrato l’attacco, l’elenco dei file con le date dice cosa ha toccato, il database dice cosa ha lasciato. Il nostro lavoro parte da lì e comprende file, database, attività pianificate e processi del server, con l’analisi dei log per individuare il punto d’ingresso. La pulizia di un’installazione WordPress è garantita entro 6, 12 o 24 ore a seconda dell’urgenza; se sei nelle prime ore di un incidente e hai dubbi su cosa fare, scrivici anche solo per sapere quali passi mettere in sicurezza prima.

IL PROSSIMO PASSO

Il tuo sito
è infetto?

Ogni ora conta: il malware continua a colpire visitatori e clienti, e Google, l’hosting e le blacklist non aspettano. Scegli il piano, paga online e condividi gli accessi: la bonifica parte subito, a prezzo fisso e con tempi garantiti.

Richiedi la bonifica

Ti porta ai piani: bonifica entro 6, 12 o 24 ore dalla ricezione degli accessi.

MANAGED SERVER S.R.L.info@rimozionemalware.com +39 02 5656 9681

Lunedì – venerdì · 09:30 – 19:30

Preferisci un modulo online?
Contattaci su managedserver.it ↗