Sei un recruiter? Clicca qui!
Antispam Contact Form 7 bloccare i bot senza CAPTCHA con uno snippet PHP

Antispam Contact Form 7: bloccare i bot senza CAPTCHA con uno snippet PHP

Scritto da Sergio Pinna il

29/04/2026

Nota importante

Questo snippet non sostituisce strumenti antispam più avanzati come Akismet, Turnstile o reCAPTCHA. È un primo livello di protezione leggero, utile per bloccare gli invii automatici più semplici senza disturbare gli utenti reali.

Contact Form 7 è uno dei plugin più utilizzati su WordPress per creare moduli di contatto.
È leggero, flessibile, gratuito e permette di costruire form anche abbastanza complessi senza dover installare page builder o sistemi troppo pesanti. Per questo motivo è presente su tantissimi siti: blog personali, siti aziendali, landing page, portfolio, siti istituzionali e piccoli e-commerce.

Il rovescio della medaglia è che, proprio perché è così diffuso, Contact Form 7 è spesso preso di mira dagli spam bot.

Chi lavora con WordPress lo sa bene: prima o poi iniziano ad arrivare messaggi strani dal modulo di contatto. Email senza senso, testi pieni di link, richieste improbabili, messaggi in lingua straniera, promozioni automatiche o contenuti palesemente generati da script.

La prima soluzione che viene in mente è quasi sempre la stessa: aggiungere un CAPTCHA.
Il CAPTCHA, però, non è sempre la scelta migliore. A volte è efficace, certo, ma può anche peggiorare l’esperienza utente. Un modulo di contatto dovrebbe essere semplice: leggo, compilo, invio. Se prima di inviare devo riconoscere semafori, selezionare autobus, cliccare immagini o aspettare caricamenti esterni, l’esperienza diventa meno fluida.

Per questo, in alcuni casi, può essere utile aggiungere un primo livello di protezione invisibile: un controllo sul tempo di compilazione del modulo.
L’idea è molto semplice: se un modulo viene inviato troppo velocemente, probabilmente non è stato compilato da una persona reale.

Un utente umano ha bisogno di qualche secondo per leggere i campi, inserire nome, email, telefono, messaggio e cliccare sul pulsante di invio. Un bot, invece, spesso compila e invia il modulo in modo quasi istantaneo.
Quindi possiamo creare una piccola regola:

se il modulo viene inviato in meno di 3 secondi, lo considero spam.

Non è una soluzione definitiva contro ogni tipo di spam, ma è un filtro leggero, invisibile e facile da implementare. Soprattutto, non disturba l’utente reale.

In questo articolo vediamo come aggiungere questo controllo a Contact Form 7 usando il plugin Code Snippets, senza modificare direttamente il file  functions.php del tema.

Perché lo spam arriva dai moduli Contact Form 7

Lo spam nei moduli di contatto può arrivare per diversi motivi.

In molti casi si tratta di bot automatici che scansionano il web alla ricerca di form WordPress da compilare.

Questi script non visitano il sito come farebbe una persona normale. Non leggono la pagina, non valutano il contenuto e non compilano il modulo con attenzione.

Semplicemente individuano i campi del form e inviano dati automatici.

Questo succede soprattutto con moduli molto semplici, ad esempio:

  • nome;
  • email;
  • telefono;
  • oggetto;
  • messaggio;

Più il modulo è standard, più è facile per un bot tentare l’invio.

Contact Form 7 mette già a disposizione diversi strumenti antispam, ma in alcuni progetti può essere utile aggiungere un controllo personalizzato. Il vantaggio è che possiamo creare una regola specifica, adatta al comportamento che vogliamo bloccare.

Nel nostro caso vogliamo bloccare gli invii troppo rapidi.

Il principio del controllo antispam basato sul tempo

Quando una persona reale apre una pagina con un modulo di contatto, normalmente compie alcune azioni:

  1. legge il contenuto della pagina;
  2. guarda i campi del modulo;
  3. inserisce i propri dati;
  4. scrive il messaggio;
  5. controlla velocemente quello che ha scritto;
  6. clicca su “Invia”.

Anche nel caso di un modulo molto breve, difficilmente tutto questo avviene in meno di 3 secondi.

Un bot, invece, può inviare il form immediatamente dopo il caricamento della pagina, oppure simulare una richiesta POST senza nemmeno passare davvero dall’interfaccia visibile del sito.

Da qui nasce il controllo:

  • quando il modulo viene caricato, facciamo partire un piccolo timer;
  • quando l’utente clicca su “Invia”, salviamo quanti secondi sono passati;
  • se sono passati meno di 3 secondi, blocchiamo l’invio come spam.

Il tutto avviene in modo invisibile.

L’utente reale non deve fare nulla di diverso dal solito. Non vede campi aggiuntivi, non deve superare CAPTCHA e non deve cliccare caselle di controllo.

Perché usare Code Snippets invece del file functions.php

Per aggiungere questo tipo di personalizzazione a WordPress potremmo modificare il file functions.php del tema attivo.

Io però, nella maggior parte dei casi, preferisco usare un plugin come Code Snippets.

Il motivo è semplice: Code Snippets permette di aggiungere funzioni personalizzate senza toccare direttamente i file del tema.

Questo ha diversi vantaggi:

  • il codice rimane più ordinato;
  • puoi attivare o disattivare lo snippet con un clic;
  • riduci il rischio di rompere il sito modificando il tema;
  • lo snippet rimane separato dalla grafica del sito;
  • puoi gestire meglio piccole funzioni personalizzate.

Naturalmente bisogna sempre fare attenzione: anche uno snippet inserito da Code Snippets è codice PHP vero e proprio. Se il codice contiene errori, può comunque creare problemi al sito.

Per questo conviene sempre testare prima su un ambiente di staging oppure, almeno, avere un backup recente.

Lo snippet completo per bloccare gli invii troppo rapidi su Contact Form 7

Questo è il codice completo da inserire in Code Snippets:

/**
 * Antispam leggero per Contact Form 7
 * Blocca gli invii troppo rapidi del modulo.
 */

add_filter('wpcf7_form_elements', 'sergio_cf7_add_elapsed_time_field');

function sergio_cf7_add_elapsed_time_field($content) {
    $hidden_field = '<input type="hidden" name="_cf7_elapsed_time" value="">';

    return $content . $hidden_field;
}


add_action('wp_footer', 'sergio_cf7_elapsed_time_script');

function sergio_cf7_elapsed_time_script() {
    ?>
    <script>
    document.addEventListener('DOMContentLoaded', function () {
        const forms = document.querySelectorAll('form.wpcf7-form');

        forms.forEach(function (form) {
            const startTime = Date.now();

            form.addEventListener('submit', function () {
                const field = form.querySelector('input[name="_cf7_elapsed_time"]');

                if (!field) {
                    return;
                }

                const elapsedSeconds = Math.floor((Date.now() - startTime) / 1000);
                field.value = elapsedSeconds;
            });
        });
    });
    </script>
    <?php
}


add_filter('wpcf7_spam', 'sergio_cf7_spam_time_check');

function sergio_cf7_spam_time_check($spam) {
    if ($spam) {
        return $spam;
    }

    $elapsed_time = isset($_POST['_cf7_elapsed_time'])
        ? absint(wp_unslash($_POST['_cf7_elapsed_time']))
        : 0;

    if ($elapsed_time < 3) {
        $submission = WPCF7_Submission::get_instance();

        if ($submission) {
            $submission->add_spam_log(array(
                'agent'  => 'sergio_cf7_time_check',
                'reason' => 'Modulo inviato troppo velocemente.',
            ));
        }

        return true;
    }

    return false;
}

Come aggiungere lo snippet su WordPress

Per inserire il codice, puoi procedere così:

  1. accedi alla bacheca WordPress;
  2. vai su Snippet > Aggiungi nuovo;
  3. assegna un titolo allo snippet, ad esempio Antispam Contact Form 7 controllo tempo;
  4. incolla il codice PHP;
  5. imposta lo snippet per l’esecuzione sul front-end del sito;
  6. salva e attiva.

Se usi già Code Snippets per altre personalizzazioni, ti consiglio di dare sempre nomi molto chiari agli snippet. Dopo qualche mese, quando il numero di funzioni aumenta, diventa molto più facile capire cosa fa ogni blocco di codice.

Un nome come “Snippet 1” o “Codice CF7” non aiuta.

Meglio qualcosa di descrittivo, ad esempio:

CF7 - Antispam controllo tempo invio modulo

Cosa fa esattamente questo codice

Lo snippet è composto da tre parti.

La prima parte aggiunge un campo nascosto al modulo di Contact Form 7:

add_filter('wpcf7_form_elements', 'sergio_cf7_add_elapsed_time_field');

function sergio_cf7_add_elapsed_time_field($content) {
    $hidden_field = '<input type="hidden" name="_cf7_elapsed_time" value="">';

    return $content . $hidden_field;
}

Questo campo non è visibile all’utente, ma viene inviato insieme agli altri dati del form.

Il campo si chiama:

_cf7_elapsed_time

All’inizio il suo valore è vuoto.

Sarà il JavaScript ad aggiornarlo nel momento in cui l’utente invia il modulo.

Il ruolo del JavaScript

La seconda parte dello snippet aggiunge un piccolo script nel footer del sito.

add_action('wp_footer', 'sergio_cf7_elapsed_time_script');

Lo script cerca tutti i moduli Contact Form 7 presenti nella pagina:

const forms = document.querySelectorAll('form.wpcf7-form');

Per ogni modulo registra il momento in cui la pagina è stata caricata:

const startTime = Date.now();

Quando l’utente prova a inviare il modulo, lo script calcola quanti secondi sono passati:

const elapsedSeconds = Math.floor((Date.now() - startTime) / 1000);

Poi inserisce questo valore nel campo nascosto:

field.value = elapsedSeconds;

In pratica, se apro la pagina e invio il modulo dopo 8 secondi, il campo nascosto conterrà il valore 8.

Se invece il modulo viene inviato dopo 1 secondo, il campo conterrà 1.

Il controllo lato PHP

La terza parte dello snippet è quella che decide se l’invio deve essere considerato spam.

add_filter('wpcf7_spam', 'sergio_cf7_spam_time_check');

Il filtro wpcf7_spam permette di dire a Contact Form 7 se un determinato invio deve essere trattato come spam.

All’interno della funzione controlliamo prima se il messaggio è già stato classificato come spam da altri sistemi:

if ($spam) {
    return $spam;
}

Questa parte è importante perché evita di sovrascrivere controlli antispam già esistenti.

Poi leggiamo il valore del campo nascosto:

$elapsed_time = isset($_POST['_cf7_elapsed_time'])
    ? absint(wp_unslash($_POST['_cf7_elapsed_time']))
    : 0;

Se il valore è inferiore a 3, blocchiamo l’invio:

if ($elapsed_time < 3) {
    return true;
}

Restituire true significa: questo messaggio è spam.

Se invece sono passati almeno 3 secondi, la funzione restituisce false e il modulo può proseguire normalmente.

Perché ho scelto 3 secondi

Il valore di 3 secondi è una soglia abbastanza prudente.

Un essere umano difficilmente riesce ad aprire una pagina, leggere il form, compilare i campi e inviare tutto in meno di 3 secondi.

Allo stesso tempo, 3 secondi non sono un limite fastidioso per l’utente reale.

Se una persona compila normalmente il modulo, non si accorgerà nemmeno dell’esistenza di questo controllo.

Naturalmente puoi modificare la soglia in base al tipo di modulo.

Se hai un modulo molto semplice, 3 secondi possono andare bene.

Se invece hai un modulo più lungo, con molti campi o con una textarea obbligatoria, potresti aumentare il limite a 5 secondi.

Per farlo, ti basta modificare questa riga:

if ($elapsed_time < 3) {

in questo modo:

if ($elapsed_time < 5) {

Io eviterei di impostare un valore troppo alto, come 10 o 15 secondi, perché potresti iniziare a bloccare utenti reali che compilano molto velocemente, magari perché usano l’autocompletamento del browser.

Perché non usare direttamente un timestamp PHP

Una possibile alternativa sarebbe inserire nel modulo un timestamp generato da PHP e poi confrontarlo con l’orario dell’invio.

Per esempio:

if ((time() - $time) < 3) {
    return true;
}

L’idea è corretta, ma sui siti WordPress moderni bisogna considerare un aspetto importante: la cache.

Se una pagina viene servita da un plugin di cache, da una cache server o da una CDN, un valore generato lato PHP potrebbe non essere sempre aggiornato come ci aspettiamo.

Per questo, in questo caso, preferisco usare JavaScript per calcolare il tempo trascorso direttamente nel browser dell’utente.

Il codice diventa più semplice da spiegare e più adatto a un contesto reale, dove spesso sono presenti plugin di ottimizzazione, cache, minificazione e sistemi di performance.

Questo metodo blocca tutto lo spam?

No.

Ed è importante essere chiari.

Questo snippet non è una soluzione definitiva contro ogni tipo di spam.

Serve soprattutto a bloccare gli invii automatici più semplici, cioè quelli che compilano e inviano il modulo troppo velocemente.

Un bot più evoluto potrebbe aspettare qualche secondo prima di inviare il form. Oppure potrebbe simulare un comportamento più simile a quello umano.

Per questo motivo il controllo sul tempo va visto come un primo livello di protezione, non come l’unico sistema antispam del sito.

In molti casi, però, proprio questo primo livello può ridurre una parte degli invii inutili senza introdurre barriere per gli utenti reali.

E questa è la cosa interessante: non stiamo aggiungendo complessità all’esperienza utente.

Il modulo resta pulito.

L’utente non vede nulla.

Il controllo avviene in silenzio.

Quando conviene usare questo controllo antispam

Questo tipo di snippet è utile quando vuoi una protezione leggera e non invasiva.

È particolarmente adatto se:

  • ricevi spam generico dal modulo di contatto;
  • non vuoi inserire subito un CAPTCHA;
  • vuoi evitare plugin aggiuntivi solo per una piccola funzione;
  • usi già Contact Form 7;
  • usi già Code Snippets;
  • vuoi mantenere il form semplice e veloce;
  • vuoi migliorare la qualità degli invii senza complicare la vita agli utenti.

Lo vedo molto bene su siti vetrina, portfolio, landing page locali, siti professionali e moduli di richiesta informazioni.

Per esempio, in un sito di un professionista, di una piccola azienda o di un’attività locale, il modulo di contatto deve essere il più immediato possibile.

Se una persona vuole chiedere un preventivo, prenotare una consulenza o inviare una richiesta, non dovrebbe trovarsi davanti un percorso inutilmente complesso.

In questi casi, un filtro invisibile può essere una buona scelta.

Quando invece potrebbe non bastare

Questo snippet potrebbe non essere sufficiente se il sito riceve molto spam, se il modulo è bersaglio di attacchi continui o se i messaggi indesiderati sono molto sofisticati.

In questi casi conviene combinare più sistemi.

Per esempio:

  • controllo sul tempo di invio;
  • campo honeypot;
  • Akismet;
  • Cloudflare Turnstile;
  • reCAPTCHA;
  • blocco di parole specifiche;
  • blocco di indirizzi IP sospetti;
  • regole lato server;
  • protezioni offerte dal servizio hosting.

La soluzione migliore dipende sempre dal tipo di sito, dal traffico, dal volume di spam e dal livello di protezione necessario.

Personalmente, tendo sempre a partire dalla soluzione meno invasiva possibile.

Prima provo a bloccare lo spam senza disturbare gli utenti. Solo se non basta, aggiungo controlli più forti.

Come testare lo snippet

Dopo aver attivato lo snippet, conviene fare alcuni test.

Il primo test è molto semplice.

Apri la pagina dove si trova il modulo Contact Form 7, compila i campi molto velocemente e prova a inviare il messaggio subito, entro 1 o 2 secondi.

In questo caso il messaggio dovrebbe essere bloccato come spam.

Poi fai una seconda prova.

Ricarica la pagina, aspetta almeno 4 o 5 secondi, compila il modulo normalmente e invialo.

In questo caso il messaggio dovrebbe partire senza problemi.

Se il secondo test non funziona, controlla questi aspetti:

  • lo snippet è attivo?
  • lo snippet viene eseguito sul front-end?
  • nella pagina è presente un modulo Contact Form 7?
  • ci sono errori JavaScript nella console del browser?
  • qualche plugin di ottimizzazione sta ritardando o modificando gli script?
  • il tema sta caricando correttamente il footer di WordPress?

Quest’ultimo punto è importante: se il tema non richiama correttamente wp_footer(), lo script potrebbe non essere stampato nella pagina.

Un controllo utile anche per capire meglio lo spam

Nel codice ho inserito anche questa parte:

$submission = WPCF7_Submission::get_instance();

if ($submission) {
    $submission->add_spam_log(array(
        'agent'  => 'sergio_cf7_time_check',
        'reason' => 'Modulo inviato troppo velocemente.',
    ));
}

Questa sezione non è indispensabile per bloccare lo spam, ma è utile per avere una traccia del motivo per cui un messaggio è stato bloccato.

In pratica, se Contact Form 7 classifica l’invio come spam a causa di questo controllo, viene aggiunta una nota nel log dello spam.

Questo può essere comodo in fase di test o debug, perché ti permette di capire se il blocco è stato causato proprio dal controllo sul tempo.

Quando si lavora su filtri antispam personalizzati, è sempre utile avere un minimo di tracciamento.

Altrimenti rischi di non capire se un messaggio è stato bloccato dal tuo snippet, da Akismet, da reCAPTCHA o da qualche altra regola.

Attenzione agli utenti reali

Quando si aggiunge un controllo antispam, bisogna sempre trovare un equilibrio.

Da una parte vogliamo bloccare i bot.

Dall’altra non vogliamo creare problemi agli utenti veri.

Per questo consiglio di non esagerare con la soglia minima.

Bloccare gli invii sotto i 3 secondi è abbastanza ragionevole.

Bloccare gli invii sotto i 10 secondi potrebbe essere già più rischioso, soprattutto se il modulo è breve e se l’utente usa l’autocompletamento del browser.

Un buon filtro antispam non dovrebbe mai diventare un ostacolo per chi vuole davvero contattarti.

La priorità resta sempre quella: ricevere richieste reali.

Una possibile variante: applicare il controllo solo ad alcuni moduli

Lo snippet visto sopra viene applicato a tutti i moduli Contact Form 7 presenti nel sito.

Nella maggior parte dei casi va benissimo.

Però potresti voler applicare il controllo solo a un modulo specifico, ad esempio solo al modulo contatti principale e non ad altri form.

In quel caso si può aggiungere un controllo sull’ID del modulo.

Questa variante è utile se sul sito hai form molto diversi tra loro: richiesta preventivo, newsletter, candidatura, contatto rapido, iscrizione evento e così via.

Per un sito semplice, però, io partirei dalla versione generale.

Meno complicazioni ci sono, meglio è.

Consiglio pratico: non usare un solo sistema antispam

Il controllo sul tempo è utile, ma dà il meglio quando viene affiancato ad altre piccole attenzioni.

Per esempio, puoi lavorare anche su:

  • testi dei campi più specifici;
  • validazione corretta dei campi obbligatori;
  • campo email ben configurato;
  • messaggi di errore chiari;
  • eventuale campo honeypot;
  • protezione server;
  • aggiornamento costante di WordPress, tema e plugin.

Lo spam non si combatte sempre con una singola soluzione miracolosa.

Spesso si riduce con più livelli leggeri che lavorano insieme.

Il vantaggio di questo approccio è che puoi mantenere il sito veloce, il form semplice e l’esperienza utente pulita.

Conclusione

Lo spam sui moduli di contatto WordPress è un problema molto comune, soprattutto quando si usa un plugin popolare come Contact Form 7.

Aggiungere un CAPTCHA può essere una soluzione, ma non sempre è la prima strada da percorrere. In molti casi conviene partire da controlli meno invasivi, capaci di bloccare almeno una parte degli invii automatici senza disturbare gli utenti reali.

Il controllo sul tempo di compilazione va proprio in questa direzione.

Se il modulo viene inviato troppo velocemente, probabilmente non è stato compilato da una persona. Con poche righe di codice possiamo intercettare questo comportamento e dire a Contact Form 7 di trattare quell’invio come spam.

Il risultato è un filtro invisibile, leggero e abbastanza semplice da gestire.

Non elimina tutto lo spam, ma può aiutare a ridurre gli invii automatici più banali.

E soprattutto non peggiora l’esperienza di chi vuole davvero contattarti.

Per un sito professionale, questa è spesso la strada migliore: proteggere il modulo, ma senza trasformarlo in un percorso a ostacoli.

Potrebbe interessarti anche...

Perché scegliere WordPress come CMS per il sito della tua attività

Perché scegliere WordPress come CMS per il sito della tua attività

21/09/2026

WordPress è uno dei CMS più scelti da aziende, professionisti e attività locali perché permette di creare siti web flessibili, personalizzabili e facili da aggiornare nel tempo. In questo articolo vediamo, con un linguaggio semplice e non tecnico, perché WordPress può essere una scelta intelligente per chi vuole un sito professionale, gestibile, ottimizzabile per Google e capace di crescere insieme alla propria attività.

Leggi l'articolo
PDF in noindex e protetti su WordPress: come farlo bene senza confondere SEO e sicurezza

PDF in noindex e protetti su WordPress: come farlo bene senza confondere SEO e sicurezza

14/09/2026

I PDF caricati su WordPress possono essere indicizzati da Google o raggiunti tramite URL diretto se non vengono gestiti correttamente. In questo articolo vediamo come impostarli in noindex tramite X-Robots-Tag, perché il robots.txt non basta, come disattivare le pagine allegato e quali soluzioni usare per proteggere davvero i file riservati.

Leggi l'articolo
WordPress e AI: come l’intelligenza artificiale può aiutare il tuo sito senza sostituire il lavoro umano

WordPress e AI: come l’intelligenza artificiale può aiutare il tuo sito senza sostituire il lavoro umano

07/09/2026

Sommario[ Nascondi ] WordPress rimane la base, l’AI diventa un assistente L’AI può aiutare nella scrittura dei contenuti L’AI può aiutare con SEO e idee per il blog L’AI può rendere più semplice la gestione del sito L’AI non sostituisce una strategia L’AI non conosce davvero la tua azienda AI e immagini: utile, ma con

Leggi l'articolo

Hai una domanda su questo articolo?

Scrivimi pure nei commenti: ti risponderò il prima possibile con un suggerimento pratico.

...aspetta un attimo!

Hai un’idea per un sito, una pagina da migliorare o un progetto ancora da mettere a fuoco? Raccontamelo: possiamo capire insieme da dove partire.

Parlami della tua idea