Spam e anti-bot WordPress: fermare i bot senza bloccare gli utenti veri

I form di contatto e i commenti sono il bersaglio preferito dei bot: spam, brute force, scraping. Ma la risposta non è mettere tre CAPTCHA uno sopra l'altro — è una difesa a strati che ferma i bot automatici e lascia passare gli umani. Honeypot, rate limiting, challenge invisibili: cosa funziona davvero.
Lo spam sui form è il primo sintomo che un sito WordPress è esposto. Arriva a ondate: periodi di calma seguiti da centinaia di messaggi identici in una notte. I bot scansionano il web alla ricerca di form esposti e li usano per spam di link, tentativi di injection e, sempre più spesso, probing per vulnerabilità. La reazione istintiva è mettere un CAPTCHA — ma il CAPTCHA visibile è l'arma più blunta e più fastidiosa per l'utente vero.
Il problema del CAPTCHA tradizionale non è solo l'esperienza: è che i bot moderni lo risolvono. I servizi di risoluzione CAPTCHA costano pochi centesimi per risoluzione, e i bot li usano. Un CAPTCHA che un bot supera e un umano fatica è il peggior compromesso possibile. La difesa moderna è a strati, e il CAPTCHA visibile è l'ultima risorsa, non la prima.
Honeypot: la trappola invisibile
Il honeypot è un campo form nascosto agli umani ma visibile ai bot. I bot compilano tutti i campi, anche quelli nascosti con CSS; gli umani no. Se il campo honeypot è compilato, la sottomissione è di un bot e viene scartata. È invisibile all'utente, non richiede interazione, e ferma la maggior parte dei bot automatici. Il limite è che un bot sofisticato può imparare a saltare i campi nascosti — per questo non è l'unica difesa, ma la prima.
// Honeypot nel form: un campo nascosto che gli umani non vedono
<input type="text" name="website_url"
style="position:absolute;left:-9999px;"
tabindex="-1" autocomplete="off" />
// Validazione lato server: se compilato, è un bot
add_filter( 'wpcf7_spam', function( $spam ) {
if ( ! empty( $_POST['website_url'] ) ) {
return true; // spam — scarta
}
return $spam;
} );
// Per un form custom (non Contact Form 7):
if ( ! empty( $_POST['website_url'] ) ) {
wp_die( 'Errore: sottomissione non valida.' );
}Rate limiting: fermare i volumi, non i singoli
Il rate limiting è la difesa contro i volumi: se un IP sottomette 50 form in un minuto, non è un umano. Si implementa a livello di server (Nginx, WAF) o di applicazione, e blocca l'IP dopo una soglia. Il limite è che i bot usano reti di IP — botnet — quindi bloccare un IP non ferma l'attacco, lo sposta. Il rate limiting è efficace contro i bot non distribuiti e come segnale di allarme, non come difesa unica.
La difesa più moderna è la challenge invisibile: servizi come Cloudflare Turnstile o hCaptcha analizzano il comportamento del browser — interazioni, timing, fingerprint — e assegnano un punteggio. Se il punteggio è basso, mostrano una challenge; se è alto, lasciano passare senza interazione. L'utente vero non vede nulla; il bot viene sfidato o bloccato. È il compromesso migliore tra sicurezza ed esperienza.
// Cloudflare Turnstile: challenge invisibile (no CAPTCHA visibile)
// 1. Registrare il site su Cloudflare Turnstile, ottenere sitekey + secret
// 2. Nel form, caricare lo script di Turnstile:
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js"
async defer></script>
<div class="cf-turnstile"
data-sitekey="TUO_SITEKEY"></div>
// 3. Validazione server-side del token Turnstile
add_filter( 'wpcf7_spam', function( $spam ) {
$token = $_POST['cf-turnstile-response'] ?? '';
$resp = wp_remote_post( 'https://challenges.cloudflare.com/turnstile/v0/siteverify', [
'body' => [
'secret' => getenv( 'TURNSTILE_SECRET' ),
'response' => $token,
],
] );
$data = json_decode( wp_remote_retrieve_body( $resp ), true );
return empty( $data['success'] );
} );La difesa a strati funziona perché ogni strato ferma una classe diversa di bot. L'honeypot ferma i bot più ingenui. Il rate limiting ferma i volumi. La challenge invisibile ferma i bot sofisticati. Un CAPTCHA visibile, se proprio serve, è l'ultimo strato per i casi che gli altri non hanno fermato — ma se lo stai mostrando a tutti gli utenti, gli strati precedenti non stanno lavorando. Un audit di sicurezza include la verifica dei form esposti e della loro difesa: spesso si scopre che il form di contatto è la porta più aperta del sito.
Verifica che i tuoi form non siano la porta aperta del sito.
Un audit di sicurezza individua i form esposti, le difese anti-bot mancanti e le configurazioni deboli prima che diventino un problema.
Articoli correlati

Zero-day WordPress: cosa fare quando esce una vulnerabilità critica
Leggi
Rinnovo certificato SSL WordPress: automatizzare Let's Encrypt senza farsi trovare scoperti
Leggi
