Antispam senza Javascript

26 marzo 2019 webdev

Quando si mette una form contatti nel proprio sito si viene inondati di spam. Il metodo scelto di solito per evitare lo spam è il CAPTCHA, ma di solito viene usato tramite soluzioni javascript già pronte. Ma io volevo un CAPTCHA senza javascript.

Sembra che ormai il mestiere di sviluppatore web si sia ridotto da “programmatore” ad “assemblatore”: framework, librerie, incorporamento di soluzioni prefabbricate. Nessuno si fa più “in casa” quasi niente. Le protezioni dallo spam non fanno eccezione, prova ne sia la pervasiva presenza, ad esempio, del reCAPTCHA di Google.

Nel mio piccolo posso dire che ci sono periodi in cui il numero di email di spam ricevute è maggiore del numero di pagine visualizzate. È interessante notare come ci siano delle vere e proprie “ondate” periodiche di spam alle quali seguono periodi di calma. Un giorno mi sono rotto i c@gli@ni e ho deciso che dovevo metterci un freno, ma senza usare codice di qualcun altro e questo per due motivi principali:

  1. il mio sito deve funzionare anche senza javascript

  2. non intendo far eseguire al browser dei miei visitatori del codice proveniente da altri siti, specialmente quelli “evil”…

Un primo approccio

La soluzione proposta da molti è di inserire nella form contatti un campo nascosto vuoto, ovvero qualcosa come:

<input type="hidden" name="link" ...

I visitatori umani non lo vedranno e quindi al submit della form risulterà vuoto mentre gli spambot1, che non “leggono” la pagina ma fanno la scansione del codice HTML, vedendo un campo disponibile ci scriveranno qualcosa. Questo aveva una logica qualche anno fa, quando gli spambot erano ancora abbastanza sempliciotti ma oggi sono perfettamente in grado di riconoscere l’attributo hidden e quel campo non lo toccano. Questa prima implementazione è stata un fallimento completo.

Un CAPTCHA rudimentale

Visto che molti antispam che ho incontrato si basavano sulla soluzione di semplici operazioni aritmetiche, ho pensato di far risolvere un’addizione per poter inviare la form. Nello script vengono scelti due numeri a caso tra 0 e 9 (in PHP si può usare la funzione rand) e si stampa a video l’operazione che il visitatore dovrà risolvere. I numeri vengono re-inviati insieme alla form e si controlla che la loro somma equivalga al numero inserito dal visitatore.

Però gli spambot ormai hanno fatto le scuole elementari e riescono a leggere (e ovviamente risolvere) la domandina. Forse l’unica cosa che, ancora per poco, non sanno fare benissimo è vedere le immagini e allora…

CAPTCHA 2 la vendetta

La versione successiva vede la sostituzione dei numeri stampati a video come testo con delle immagini dei numeri. Mi sono preparato delle immaginette per tutte le cifre, per il segno di addizione e per il segno di uguale. Incredibilmente funziona! Però…

CAPTCHA 3 sempre meglio

Non so perché ma avere 12 immagini solo per l’antispam mi dava fastidio. Senza contare che, un giorno, uno spambot potrebbe capire che 1.png forse significa 1 e allora gli ci vorrebbe poco a fare 1+1 (ah ah). Poi mi sono ricordato che, nei CSS, a volte usavo le data URI per le icone o gli sfondi. Si codifica l’immagine in base64 ottenendo una lunga stringa di testo. È lo stesso meccanismo usato per inviare file binari tramite email. Tale testo verrà poi usato al posto dell’immagine usando data:image.... I browser odierni sono perfettamente in grado di visualizzare tali immagini.

<img src="data:image/png;base64,iVBORw0KGg... etc etc

Le immagini codificate (ovvero le stringhe) sono inserite in un array dal quale ne verranno scelte due a caso. Questo meccanismo si è rivelato molto efficace e ha il pregio, rispetto alla soluzione precedente, di poter essere messo on-line con un solo file, visto che le immagini sono contenute in esso sotto forma di stringhe. Ha l’ovvio svantaggio di far crescere le dimensioni del file, anche se siamo sempre nell’ordine di qualche decina di KB.

Per controllare il funzionamento di questa soluzione ho cominciato a registrare tutte le comunicazioni ritenute spam in un file di log. In realtà, più che un log, sembra un bordello visto quello che scrivono. Comunque, per curiosità, questo è il file spam.txt nel quale registro data, email, oggetto, messaggio, indirizzo IP e user agent.

Fine (?)

Finché funziona, per me il problema dello spam finisce qui. Niente javascript, niente voluminose librerie da far scaricare ai visitatori, niente legame a soluzioni altrui, specialmente di quelli che registrano brevetti quantomeno discutibili


  1. Contrazione di “spam” e “robot”, qui inteso come programma autonomo.