Distinguere l’uomo dalla macchina in modo accessibile

Risolvimi il quesito e ti farò continuare

I due precedenti casi studiati, sono basati su sistemi di riconoscimento non invasivo: basati su fattori che hanno cercato di identificare l’uomo non tramite un interazione forzata di riconoscimento da parte del sistema quanto per mezzo del tempo impiegato alla compilazione del modulo.

Un sistema automatico, ha una fase di acquisizione delle informazioni sul modulo e una seconda fase che si ripete più e più volte nel tempo, mantenendo però i nomi dei campi precedentemente acquisito. Il bot è stupido quanto furbo (scusate il gioco di parole): non immagina che ogni volta il sistema cambia i nomi dei campi.

Il sistema che andiamo a presentare in questo paragrafo, è basato sull’interazione tra uomo e macchina. Quindi mentre gli altri sistemi non lo erano questo risulta estremamente invasivo.

Per invasivo intendo un sistema che richieda un’interazione forzata dell’utente il cui procedimento non è collegato per logica alle informazioni che si passano sul modulo.

Il concetto si basa sul prendere sempre un numero di sessione (ma potrebbe essere un ticket generato come nel paragrafo precedente, oppure un codice univoco scritto nel database), e riportarlo a video senza troppe elaborazioni ma mostrando il codice in caselle ciascuna contenente un singolo carattere.

Un qualcosa tipo quello che segue:

+---+---+---+---+---+---+---+---+---+---+
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 |
+---+---+---+---+---+---+---+---+---+---+

Ed un elenco di indicazioni per compilare un campo tipo:

  1. Riportare il codice presente nella casella numero uno
  2. A seguire riportare il codice presente nella casella numero sette
  3. A seguire riportare il codice presente nella casella numero quattro

e così a seguire.

Consentendo quindi all’utente di seguire le istruzioni per compilare il modulo.

Il pro di questa soluzione è che risulta troppo complesso per un sistema di intelligenza artificiale il quale dovrebbe affrontare problemi quali: riconoscimento delle caselle con i relativi codici, ed interpretare i passaggi descritti nell’elenco puntato che seguirebbe le caselle.

Il contro è che comunque l’utente è obbligato a compilare un campo che non gli servirà a nulla: una perdita di tempo a noi utile ma per lui praticamente inutile!

Andiamo a sviluppare la soluzione.

Il codice HTML relativo alla pagina avrà un campo Cognome ed un campo Nome non seguiti da alcun suffisso ma ci saranno altri 2 campi, uno dei quali nascosti, che riporta un codice di codifica particolare.

<form method="post" action="scrivi.php">
  <input type="hidden" value="<?=$codice?>" name="ticket" />
  <p>
    <label for="nome">Nome</label>
    <input type="text" value="" id="nome" name="nome" />
  </p>
  <p>
    <label for="nome">Cognome</label>
    <input type="text" value="" id="conome" name="cognome" />
  </p>
  <p>
    <input type="submit" name="conferma" value="conferma" />
  </p>
  <?php captcha($codice); ?>
</form>

$codice sarà elaborato secondo questo algoritmo:

$codice = md5(session_id());

Come potrete notare, viene richiamata una funzione denominata Captcha prima del submit.

Questa funzione si preoccuperà di elaborare il codice ottenuto elaborandolo e riportando direttamente a video la trasposizione dei dieci codici e delle istruzioni per la compilazione del campo captcha.

$numeri = array('uno', 'due', 'tre', 'quattro',
                'cinque', 'sei', 'sette', 'otto', 'nove', 'dieci');
$posizioni = array('prima', 'seconda', 'terza', 'quarta',
                   'quinta', 'sesta', 'settima', 'ottava', 'decima', 'undicesima');

// I primi 5 caratteri dell'ID di sessione codificato saranno considerati per la definizione dell'elenco
$l = substr($codice, 0, 10);
echo('<ol>');
for($i=0; $i<strlen($l); $i++){
  echo('<licolor: rgb(51, 153, 51);">. $i . '">' . $l[$i] . '</li>');
}
echo('<ol>');

// Gli ultimi cinque caratteri identificheranno l'elenco
$r = substr($codice, -5);
echo('<label for="captcha">Compilare il codice di controllo seguendo le istruzioni elencate:</label>');
echo('<ul>');
$buffer = '';
for($i=0; $i < strlen($r); $i++ ){
  $indice_1_10 = (ord($r[$i])/1.1);
  $decimal = $indice_1_10 - intval($indice_1_10);
  $indice = (ord($r[$i])%10);
  if($buffer != '') $buffer = 'a seguire ';
  if($decimal >0.5) $buffer .= 'riportare il valore indicato nella casella numero ' . $numeri[$indice];
               else $buffer .= 'riportando il valore presente nella ' . $posizioni[$indice] . ' casella.';
  echo('<li>' . $buffer . '</li>');
}
echo('</ul>');
echo('codice di controllo: <input type="text" name="captcha" id="captcha" value="" /> ');

La funzione lato server che si preoccuperà di verificare se eventualmente il captcha fornito è corretto è il seguente:

function valida_captcha($codice, $captcha){

  // I primi 5 caratteri dell'ID di sessione codificato saranno considerati per la definizione dell'elenco
  $l = substr($codice, 0, 10);

  // Gli ultimi cinque caratteri identificheranno l'elenco
  $r = substr($codice, -5);
  $buffer = '';
  for($i=0; $i < strlen($r); $i++ ){
    $indice_1_10 = (ord($r[$i])/1.1);
    $decimal = $indice_1_10 - intval($indice_1_10);
    $indice = (ord($r[$i])%10);
    if($l[$indice] != $captcha[$i]){
      echo('codice non valido sul ' . $i . 'o carattere');
      return false;
    }
  }
  return true;
}

Mentre il codice che utilizzerà tale funzione è semplicemente:

if(isset($_POST) &amp;&amp; valida_captcha($ticket, $_POST['captcha'])){
  // Il codice è stato identificato e quindi è possibile scrivere le informazioni
  $cognome = $_POST['cognome'];
  $nome = $_POST['nome'];
}else{
  // Se non sono stati passati dati in POST faccio un redirect alla
  // pagina di visualizzazione dei risultati
  echo('errore');
  exit();
}

Conclusioni

I tre casi riportati sono comunque particolarmente vulnerabili così come descritti, ci sarebbe bisogno di una maggiore complessità per avere una quasi certezza di un sistema anti spam.

Tale sicurezza può essere raggiunta magari applicando tutte e tre le soluzioni ad un unico modulo. Ma prima di farlo bisogna porsi un interrogativo: è veramente necessaria tutta questa sicurezza? Paradossalmente potrebbe essere poco conveniente mettere l’antifurto satellitare su una penna, a meno chè non valga un milione di euro! ;-)


Pubblicato

in

, ,

da

Tag:

%d blogger hanno fatto clic su Mi Piace per questo: