/dev/random

Alternative al CAPTCHA

Lo SPAM imperversa sempre di più, e sempre più spesso gli spammer sfruttano i form dei siti.

Ormai la percentuale di SPAM nelle mail ricevute ha raggiunto il 90% e gli spammer, non contenti, da alcuni anni sfruttano anche i Blog e i CMS per impestare la rete con le loro schifezze.

Per quanto riguarda le mail è un continuo inseguimento: blacklist, filtri bayesiani, OCR sulle immagini, ecc. Ma anche i siti hanno dovuto rincorrere le continue innovazioni da parte degli spammer.

CAPTCHA

CAPTCHASono quindi nati i CAPTCHA di vario tipo, che si basano sulla (presunta) incapacità dei bot di spam di “leggere” il testo contenuto in un'immagine. Il sistema ha funzionato per un po', finché i sistemi si sono evoluti e hanno iniziato a usare tecniche di OCR sui CAPTCHA stessi, facendone perdere efficacia: sono diventati via via più difficili da decodificare, ma anche per l'occhio umano oltre che per i bot.

Ne sono nati quindi nuovi tipi: dal CAPTCHA matematico (che potete ammirare nel form dei commenti di questo Blog :) ) a quello “sexy”, che si basa sulla capacità di una persona di distinguere un rappresentante bello del sesso opposto da uno brutto.

Purtroppo hanno tutti lo stesso problema: una persona con problemi di vista o qualcuno che naviga con browser testuali non li può utilizzare. Sono allora nati gli aiuti sonori ai CAPTCHA (che “pronunciano” le lettere nel CAPTCHA, per esempio), ma si scontrano col problema dell'audio sui siti: se l'utente sta ascoltando musica in sottofondo deve spegnerla, ascoltare il CAPTCHA, compilare il form, quindi riaccendere la musica

In un periodo in cui bisogna rendere la vita più semplice possibile all'utente, tutte queste complicazioni sono anacronistiche, e allontanano gli utenti.

Vediamo quindi alcune alternative, magari non perfette, ma con una buona percentuale di sicurezza.

Il campo nascosto nel form

Una prima tecnica consiste nell'aggiungere un campo di testo normale in un form, quindi di nasconderlo tramite CSS. Questa tecnica si basa sul presupposto che i bot, per sfruttare il maggior numero possibile di form, non guardano quali campi compilare, e invece li compilano tutti.

Si può quindi usare un codice come questo:

<style>
 .nascosto { display: none; }
</style>

...

<form ...>
 ...
 <div class="nascosto">
  <label for="codicesegreto">Non scrivere nulla in questo campo</label>
  <input type="text" name="codicesegreto" />
 </div>
 ...
</form>

In questo modo i browser che supportano i CSS nasconderanno l'intero div (è un esempio, naturalmente. Va adattato a come stilizzate i vostri form) e l'utente non vedrà nemmeno il campo. I browser che non supportano i CSS lo mostreranno, ma con il messaggio all'utente di non compilarlo. I bot non avranno idea di cosa si trovano davanti e lo compileranno senza pensarci (pensare? un bot??).

Lato server basta controllare che il campo “codicesegreto” del form non contenga nulla. Per esempio, in PHP:

<?php
 if (isset($_POST["codicesegreto"]) && $ POST["codicesegreto"] != "") {
  print("Ciao, bot! PRRRRRRRRRRR");
  exit;
 }
 // Normale processo di verifica degli altri campi
?>

Il codice nascosto nel form

Un'altra tecnica consiste nel nascondere un codice segreto nel form, e modificarlo via Javascript appena il form viene visualizzato:

<form...>
 ...
 <input type="hidden" id="codice" name="codicesegreto" value="1000" />
 <script type="text/javascript">
  <!--
   document.getElementById("codice").value = "mille";
  -->
 </script>
 ...
</form>

Questa tecnica si basa sul presupposto che il bot non esegua il codice javascript contenuto nel form. I browser che supportano Javascript avranno quindi codicesegreto=”mille”, mentre quelli che non lo supportano avranno codicesegreto=”1000". I valori, naturalmente, sono di pura fantasia, potete mettere quello che volete, anche valori casuali calcolati server-side prima di presentare il form, e salvati in sessione per una verifica successiva.

Lato server, al ricevimento dei dati dal form, basta appunto controllare cosa contiene quel campo. Se contiene “mille” si procede normalmente con l'analisi degli altri campi del form. Se contiene “1000” si può presentare all'utente un nuovo form, chiedendogli solo “Sei davvero una persona o sei un bot?” con un tasto submit: “Sono una persona”. Solo le persone (che hanno disattivato javascript nel browser) dovrebbero clickare su questo nuovo form, e quindi procedere al submit del form.

In PHP si può fare una cosa del genere:

<?php
 session_start();

 if (isset($_POST["codicesegreto"]) && $_POST["codicesegreto"] != "mille") {

  $_SESSION["datiform"] = $_POST;
  ?>
   <form ...>
    <label>Sei davvero una persona o un bot?</label>
    <input type="submit" name="chidicicheiosia" value="Sono una persona!" />
   </form>
  <?php
  exit;

 } else {
  // Normale procedura di controllo dei campi e di submit del form
 }
?>

Questo “giro” è un po' più oneroso per gli utenti che disabilitano Javascript, ma non gli preclude la possibilità di scrivere commenti o comunque di compilare il form. Se Javascript è attivo la procedura è totalmente automatica. Naturalmente bisogna predisporre anche la pagina aggiuntiva per il controllo della conferma, oppure modificare la logica di questa in modo da gestire sia il submit diretto che quello con conferma.

Vantaggi e svantaggi

Il vantaggio più evidente è la semplicità, sia per il programmatore che per l'utente.

L'utente non deve compilare campi aggiuntivi, non deve cercare di interpretare strane immagini deformate o fare calcoli matematici. Tutte operazioni che, spesso, non capisce nemmeno a cosa possano servire.

Il programmatore non dovrà più fare i salti mortali per distorcere il testo in modi astrusi, complicarsi la vita con le libgd, o cercare font non “OCR-izzabili”. Non dovrà nemmeno fare funzioni aggiuntive per rigenerare l'immagine al volo (via AJAX, magari) nel caso l'altra sia illeggibile. Il codice, sia HTML che PHP, è molto più pulito.

Inoltre il traffico sulla rete è molto ridotto: non c'è un'immagine che comunque occupa una decina di KiB, e c'è anche una richiesta HTTP in meno. In generale il sito è più leggero.

Altro vantaggio è che questi due sistemi possono essere combinati per raddoppiare l'efficacia.

Lo svantaggio è totalmente dipendente dall'intelligenza dei bot. Se i bot riusciranno ad adeguarsi a queste tecniche, queste perderanno d'efficacia. Per farlo, naturalmente, dovranno imparare ad interpretare sia i CSS che il Javascript, ma basterebbe adeguare un po' gli stili e il codice JS facendo le cose in modo un po' più complesso (richiamando funzioni o metodi di oggetti in JS, o usando selettori in CSS). A quel punto dovrebbero diventare veri e propri browser. Non escludo possa succedere, ma nel frattempo si potranno inventare nuove soluzioni.

Per ora dovrebbero essere più che sufficienti.