Come creare un sistema antispam (captcha) in PHP

Giovanni Canella

01/02/2013

7673

Nella maggior parte dei siti web, al momento della registrazione, dell'invio di un form per contattare l'amministratore, per inviare un commento ci è richiesto di inserire una sequenza alfa-numerica.

Azione ormai diventata automatica, tanto che non ci facciamo più caso, o non ci poniamo più tanti problemi su cosa possa servire.

Il motivo è presto detto: verificare se, a compilare i campi, sei veramente tu, oppure un bot. Questo sistema viene chiamato Captcha (Completely Automated Public Turing test to tell Computers and Humans Apart) e viene soprattutto utilizzato per impedire l'invio massiccio (spam) di messaggi indesiderati, inoltre aumenta anche la sicurezza generale del nostro sito, rendendo vani attacchi a forza bruta (bruteforce).

Obiettivo dell'articolo

In questo articolo vedremo come realizzare un sistema Captcha, scritto in PHP, inserito nel contesto di un form di registrazione.

Questo progetto avrà bisogno di essenzialmente 3 files:

  • captcha.php, file core, in cui è presente tutto il codice fondalmentale, affinchè il captcha venga creato, "incollato" in una immagine di sottofondo, e infine visualizzato correttamente.
  • ob.png, immagine, con estensione .png, rappresentante il background del captcha, può contenere qualunque elemento, basta che risulti difficile l'individuazione del testo. Più l'immagine è complessa, più si incrementerà la sicurezza dai bot, eludendo i loro meccanismi di OCR (Optimal Character Reconition), così da impossibilitarli di scannerizzare il testo. E' consigliato l'inserimento di parole e lettere con una minore opacità e posizionate vicine al vero testo.
  • form.php, in cui sarà contenuto il codice HTML che comporrà il form, e i controlli dei campi.

Iniziamo!

Apriamo l'editor che più ci aggrada (nel mio caso Komodo Edit), e creiamo un nuovo file chiamato captcha.php. Ecco la sua struttura logica:

  1. Creazione di un codice random, utilizzando la funzione sha1(), utilizzata soprattutto negli hash, e microtime(), che restituisce il timestamp attuale compresi i millisecondi.
  2. Si tronca il lungo codice con la funzione substring(), per la lunghezza che vogliamo noi, di norma 5-7 caratteri.
  3. Si procede alla creazione di un immagine, basandoci sul file (captcha.png),
  4. Si sceglie il colore del testo,
  5. Infine si "incollano" le due parti ottenendo il captcha finale.
  6. Si carica il testo in una sessione.

Ecco il codice:

session_start();

//Genero un codice di 5 cifre in maniera random.
$codice_random = sha1(microtime());
$codice_random = substr($codice_random, 0, 5);

//Creo un immagine png
$Immagine = imagecreatefrompng("captcha.png");

//Seleziono il colore del testo (RGB)
$Colore = imagecolorallocate($Immagine, 0, 0, 0);

//Creo l'immagine finale
imagestring($Immagine, 100, 35, 15, $codice_random, $Colore);

//Creo la sessione che conserva il testo random
$_SESSION['Captcha'] = $codice_random;

//Visualizzo l'immagine per il captcha
header("Content-type: image/jpeg");
imagepng($Immagine);

form.php, conterrà le seguenti righe:

<form action="#" method="post">
     Username <input name="username" type="text" /> 
     Password <input name="password" type="password" /> 
     <img alt="Captcha" src="captcha.php" style="float:left; margin-right:10px" /> 
     <input maxlength="5" name="Captcha" size="5" type="text" /> 
     <input name="submit" type="submit" value="Login" />
</form>

Dove nel tag img, non compare l'immagine nei formati classici, ma mettiamo il percorso della nostra libreria, questo perchè nel codice precedentemente scritto, abbiamo inviato l'header per far visualizzare un'immagine

header("Content-type: image/jpeg");

Infine i controlli sul captcha, per vedere se quello inserito è corretto oppure no (sempre nello stesso file).

if(isset($_POST['submit'])) {
       $Captcha = $_POST["Captcha"];

       if($_SESSION['Captcha'] !== $Captcha) {
              echo "Il codice Captcha inserito non corrisponde. Ricontrollare.";
       } else {
              echo "codice corretto!";
       }
}

Per vedere il risultato finale, ci si può collegare alla pagina Contattami di Ginho!

I più letti

Ti potrebbero interessare