Verificare i checksum di WordPress: file core modificati
Come verificare i checksum di WordPress con WP-CLI o l'API di WordPress.org, leggere gli avvisi su file modificati o extra, controllare i plugin e reinstallare il core.
Anche in: English Deutsch Français Español Polski Português Türkçe
In caso di sospetta violazione, la verifica dei checksum è un utile controllo iniziale, ma non deve ritardare il contenimento né la conservazione delle prove. Un solo comando indica se i file del core sono identici byte per byte alla versione ufficiale. I file inclusi nell'elenco ufficiale dei checksum devono corrispondere alla versione e alla lingua esatte dell'installazione. I file specifici del sito, come wp-config.php, restano fuori da questo confronto. Qualsiasi differenza è una modifica locale nota oppure qualcosa da esaminare subito.
Perché i file core di WordPress cambiano dopo un attacco
I file del core sono un ottimo nascondiglio, perché nessuno li legge. Chi gestisce un sito guarda le impostazioni di tema e plugin. Quasi nessuno apre wp-includes/load.php o conta i file in wp-admin/includes. Un attaccante può nascondere codice in un file del core caricato regolarmente, oppure aggiungere un file dall'aspetto plausibile per rientrare in seguito. Un file aggiunto non viene però eseguito solo perché si trova in una directory del core.
I checksum trasformano il «sembra tutto a posto» in un confronto verificabile. WordPress.org pubblica un hash MD5 per ogni file del core di ogni release. I file del sito vengono confrontati con quell'elenco.
Va tenuta presente anche la causa. Lo State of WordPress Security in 2026 di Patchstack è un rapporto di un fornitore del settore. Per il 2025 conta solo 6 vulnerabilità nel core di WordPress, tutte a bassa priorità. Questo dato non dice come un attaccante sia entrato nel sito. I file core modificati possono derivare da un'intrusione attraverso un plugin, un tema o credenziali rubate. Sostituire il core ripara quei file, ma resta da individuare e chiudere il punto di ingresso.
Come verificare i checksum di WordPress con WP-CLI
Ci si collega via SSH e si esegue il comando dalla directory radice di WordPress:
cd /var/www/example.com
wp core verify-checksums
Se ci si trova in un'altra directory, aggiungere --path=/var/www/example.com. Il comando va eseguito con l'utente proprietario dei file del sito, non come root. WP-CLI si rifiuta di funzionare come root, a meno di aggiungere --allow-root, ed è un comportamento sensato: da root, qualsiasi codice malevolo caricato da WordPress verrebbe eseguito a sua volta come root.
Per impostazione predefinita, WP-CLI legge la versione da wp-includes/version.php. In un sito compromesso anche quel file può essere stato modificato. Se si conosce la versione installata, conviene indicarla esplicitamente. Per le installazioni non in inglese va indicata anche la lingua (locale):
wp core verify-checksums --version=6.8.3 --locale=de_DE
Si usi il numero di versione effettivo del proprio sito, e per un sito in italiano --locale=it_IT. Su un sito pulito compare una sola riga:
Success: WordPress installation verifies against checksums.
Su un sito con problemi compaiono avvisi come questi:
Warning: File doesn't verify against checksum: wp-includes/functions.php
Warning: File should not exist: wp-includes/class-wp-cache-handler.php
Error: WordPress installation doesn't verify against checksums.
Interpretare i risultati: file modificati ed extra
I due tipi di avviso hanno significati diversi e richiedono interventi diversi.
| Output | Significato | Cosa fare |
|---|---|---|
Success: ... verifies | I file del core corrispondono | Controllare poi wp-content e il database |
File should not exist | File in più in una directory controllata | Conservare e ispezionare; rimuovere se malevolo o confermato come superfluo |
File doesn't verify | Contenuto di un file core modificato | Considerare compromesso, reinstallare il core |
Un file modificato va trattato come un problema serio, salvo che esista una patch locale legittima. Sono casi rari, e chi l'ha applicata dovrebbe averla documentata.
Un file extra è meno netto. Alcuni aggiornamenti lasciano file delle versioni precedenti, quindi un file in più non prova la presenza di malware. Un file PHP dal nome casuale in wp-includes è invece sospetto finché non è stato letto. Lo stesso vale per un file il cui nome somiglia soltanto a quello di un componente del core.
I file extra possono essere segnalati come avvisi senza che il comando fallisca: è possibile vedere righe File should not exist seguite da Success. Meglio leggere ogni avviso, senza fidarsi dell'ultima riga.
Per impostazione predefinita, il controllo dei file extra copre wp-admin e wp-includes. Alcune versioni di WP-CLI possono controllare anche la directory radice. Con wp help core verify-checksums si verifica se la propria versione offre --include-root.
Senza WP-CLI: l'API dei checksum di WordPress.org
Alcuni hosting offrono SSH ma non WP-CLI. In tal caso si può interrogare direttamente l'API dei checksum e lasciare il confronto a md5sum. Servono curl e jq:
cd /var/www/example.com
VER=6.8.3 # la versione esatta di WordPress
LOC=en_US # oppure de_DE, fr_FR, ...
(
set -e
WORK=$(mktemp -d)
trap 'rm -rf -- "$WORK"' EXIT
curl -fsS "https://api.wordpress.org/core/checksums/1.0/?version=$VER&locale=$LOC" \
-o "$WORK/response.json"
jq -er '.checksums | select(type == "object" and length > 0) | to_entries[] | select(.key | startswith("wp-content/") | not) | "\(.value) \(.key)"' \
"$WORK/response.json" > "$WORK/core.md5"
test -s "$WORK/core.md5"
md5sum -c --quiet "$WORK/core.md5"
)
Il filtro select esclude i temi e i plugin inclusi in wp-content, che potrebbero essere stati eliminati di proposito. Con --quiet, md5sum stampa solo i file che non corrispondono.
Nessun output e uno stato di uscita pari a zero indicano che i file presenti nell'elenco filtrato dei checksum corrispondono. Un errore di download, di parsing o di verifica non è un risultato pulito. La subshell usa una directory temporanea privata e si interrompe se un passaggio precedente fallisce.
Questo metodo non rileva i file extra. Per trovarli, si scarica la stessa release, ad esempio https://wordpress.org/wordpress-6.8.3.zip; per le installazioni non in inglese si usa il sito WordPress della lingua corrispondente. Si decomprime l'archivio e si confrontano le cartelle:
diff -rq wordpress/wp-includes /var/www/example.com/wp-includes
diff -rq wordpress/wp-admin /var/www/example.com/wp-admin
Le righe Only in /var/www/... indicano file in più nell'installazione. Le righe Only in wordpress/... indicano file mancanti nell'installazione. Le righe Files ... differ indicano differenze di contenuto. Vanno ispezionate anche le directory inattese.
Plugin e temi: dove i checksum smettono di funzionare
WP-CLI può controllare anche i plugin:
wp plugin verify-checksums --all
Funziona solo per i plugin ospitati su WordPress.org, perché solo per questi esistono checksum pubblicati. I plugin privi di un corrispondente set di checksum su WordPress.org non possono essere verificati in questo modo.
Se una copia nulled o manomessa mantiene slug e versione di un plugin di WordPress.org, il comando può comunque confrontarla e segnalerà i file modificati. Per i temi, WP-CLI non offre un comando integrato equivalente.
Per questi plugin e per i temi occorre procurarsi la versione installata esatta dalla fonte ufficiale o da un archivio di build affidabile. Per il codice personalizzato si usa un artefatto di release noto e integro, non una copia presa dal sito sospetto. Poi lo si confronta con la copia installata:
diff -rq ~/clean/some-premium-plugin wp-content/plugins/some-premium-plugin
Conviene anche cercare cartelle di plugin che non si riescono ad associare a nulla di ciò che è stato installato. Una cartella sconosciuta in wp-content/plugins è un chiaro segnale d'allarme. Un plugin nulled è un problema in sé, qualunque cosa mostri il diff. La guida alle vulnerabilità dei plugin spiega come sostituire plugin nulled e abbandonati.
Reinstallare il core di WordPress in sicurezza
Prima si conservano le prove e si esegue un backup completo. Poi si sostituisce il core con una copia pulita della stessa versione:
wp core download --force --skip-content --version=6.8.3
Se serve, si aggiunge --locale=de_DE o la propria lingua. Il comando sovrascrive i file del core. Non tocca wp-config.php, perché il pacchetto non contiene alcun file con quel nome. --skip-content lascia intatto wp-content.
Il comando non rimuove i file extra. Un file come wp-includes/class-wp-cache-handler.php resta dov'è, perché il download scrive solo file ufficiali. Ogni file extra va prima copiato ed esaminato. Si eliminano poi quelli malevoli o di cui si è confermata l'inutilità. Si esegue di nuovo wp core verify-checksums e si controlla che non restino avvisi inspiegati.
Cosa non dice un risultato pulito dei checksum
Un esito positivo riguarda solo il core di WordPress. Non dice nulla su:
wp-content: temi, plugin premium e personalizzati,mu-pluginseuploadswp-config.phpe.htaccess, che non figurano nell'elenco dei checksum- Il database: opzioni iniettate, spam negli articoli, account amministratore non autorizzati, eventi cron pianificati
- I file esterni a WordPress, come altri file PHP nell'account di hosting o la configurazione a livello di server
Gli attaccanti sanno quali file vengono controllati. È uno dei motivi per cui wp-content/uploads è un luogo prediletto per le web shell. Per i controlli restanti si può seguire l'elenco dei segnali di un sito hackerato. Per la cartella uploads vale la guida alle web shell.
Monitoraggio continuo dell'integrità dei file
Un controllo una tantum è utile durante un incidente. Un controllo pianificato può ridurre il tempo in cui una modifica passa inosservata, ma le alterazioni possono comunque raggiungere i visitatori prima dell'esecuzione successiva. Basta un piccolo script lanciato da cron:
#!/bin/bash
cd /var/www/example.com || exit 1
OUT=$(/usr/local/bin/wp core verify-checksums 2>&1)
if [ $? -ne 0 ] || echo "$OUT" | grep -q "Warning:"; then
echo "$OUT" | mail -s "Core checksum alert: example.com" admin@example.com
fi
Lo script va installato nel crontab dell'utente proprietario del sito, non in quello di root. Invia un avviso sia con un codice di uscita diverso da zero sia con qualsiasi warning, compresi i file extra segnalati. Conviene impostare un PATH noto oppure usare percorsi completi degli eseguibili, perché cron dispone di un ambiente limitato. Va verificato che l'avviso arrivi davvero; se necessario, si sostituisce mail con il sistema di notifica effettivamente in uso.
Per wp-content conviene mantenere una baseline propria dopo ogni aggiornamento verificato:
find wp-content/plugins wp-content/themes -type f -exec sha256sum {} + > ~/baseline-$(date +%F).sha256
La baseline va conservata fuori dalla web root, meglio ancora fuori dal server. Per cercare modifiche si esegue sha256sum -c --quiet sulla baseline dalla radice del sito. In questo modo emergono file modificati ed eliminati, ma non quelli nuovi. Per i file nuovi si confronta un nuovo elenco ottenuto con find con quello contenuto nella baseline. Dopo ogni aggiornamento legittimo va creata una nuova baseline, altrimenti il controllo successivo segnalerà le modifiche fatte dall'utente stesso.
I controlli regolari aiutano anche sul piano della conformità. L'art. 32, par. 1, lett. d), del GDPR richiede una procedura per testare, verificare e valutare regolarmente l'efficacia delle misure di sicurezza. Un controllo di integrità pianificato, con i risultati salvati, è una prova concreta di tale procedura. Il quadro più ampio è nell'articolo GDPR, art. 32 per WordPress.
Chi preferisce non mantenere script propri può usare il plugin Security Audit & Compliance di secaudit.eu, che tiene una baseline di integrità dei file e segnala file modificati e contenuti offuscati. Esegue anche la verifica dei checksum del core. Rileva e segnala; la pulizia resta compito dell'utente o della sua agenzia.
FAQ
verify-checksums funziona con multisite e installazioni non in inglese?
Sì. Una rete multisite condivide un unico set di file core, quindi un'esecuzione copre l'intera rete. Per le installazioni non in inglese va indicato il --locale corretto, perché i pacchetti localizzati possono differire da en_US.
L'avviso «File should not exist» indica sempre malware?
No. Lo generano anche file lasciati da versioni precedenti di WordPress. Si conserva una copia e si ispeziona il file. Lo si rimuove se è malevolo o se è confermato come superfluo. Codice PHP inspiegato in una cartella del core richiede però sempre un esame approfondito.
Con quale frequenza va eseguito?
Per la maggior parte dei siti aziendali è ragionevole un'esecuzione giornaliera tramite cron. Conviene eseguirlo anche dopo un incidente, dopo ogni aggiornamento del core e ogni volta che qualcuno di nuovo ottiene accesso al server.
Un attaccante può falsificare il risultato dei checksum?
I checksum provengono da WordPress.org via HTTPS. Chi controlla il server potrebbe però manomettere gli strumenti locali, come il file di WP-CLI o i binari di sistema. In caso di dubbio, si copiano i file del sito su una macchina pulita e li si confronta lì con un download nuovo della stessa release.
Controlla il tuo sito
Security Audit & Compliance è il plugin WordPress di secaudit.eu: cerca malware, spam nascosto, file core modificati e codice vulnerabile, e collega i risultati all’art. 32 del GDPR, all’art. 21 della NIS2 e alla OWASP Top 10.
Scopri cosa controlla il plugin