Captchas – Spambots den Kampf ansagen

Captchas – Spambots den Kampf ansagen
Von Lars Ebert am 22.07.10, 21:38
Kategorien: Programmieren and Tutorials

Jeder, der ein Gästebuch, ein Forum oder sonst eine Webanwendung programmiert, in der Nutzereingaben gespeichert werden oder Traffic verursacht wird, muss sich darüber im Klaren sein, dass diese Nutzereingaben auch von Spambots generiert werden können. Ich habe es einmal erlebt, das ein Spambot über Nacht in einem von mir programmierten Forum hunderte neuer Benutzer mit Spamnamen anlegte.

So etwas ist nicht nur ärgerlich und viel Arbeit für den Administrator, das kann auch teuer werden! Denn jeder Aufruf der Seite erzeugt Traffic, und wenn ein Bot mal eben 1000 Aufrufe sendet, kommt eine Menge Traffic zusammen.

Doch was kann man bitte dagegen tun?

Die Lösung ist eben so simpel wie genial. Man stellt dem Nutzer einfach eine Aufgabe, die für ihn kein Problem darstellt, für jeden Spambot aber zur unüberwindbaren Hürde wird.

Die gängigste Möglichkeit ist ein so genanntes Captcha, eine Grafik mit verfremdeten Zeichen, die vom Menschen erkannt werden müssen.

Leider hat ein Captcha auch Nachteile, zum Beispiel ist es nicht sehbehindertengerecht und der Browser muss zwingend Bilder anzeigen. Nutzer eines Textbrowsers wie Lynx bleiben auf der Strecke. Deshalb sollte immer eine Alternative zum Captcha geboten sein, wie zum Beispiel ein Audiocaptcha oder eine Servicehotline. Dann steht der Verwendung eines Captchas nichts mehr im Weg.

Ein solches Captcha selber zu realisieren, ist gar nicht so schwer, wie es aussieht, man braucht nur ein PHP-Script, dass die Grafik dynamisch generiert, eine Hintergrundgrafik und eine Schriftart.

Die Schriftart kann man leicht von FontCenter.de downloaden. Sie sollte die Endung .ttf haben.

Das Bild kann man mit einem Grafikprogramm leicht als PNG selbst erstellen. Hier ein Beispiel für das Hintergrundbild:

Beispiel für ein Hintergrundbild Beispiel für ein Hintergrundbild

Wer keine Lust hat, einen eigenen Hintergrund zu erstellen, kann gerne diesen Hintergrund verwenden.

Nun muss noch das PHP-Script her, dass das Captcha mit Text füllt.

<?php
 session_start();

 unset($_SESSION['captcha']);

 # Diese Funktion erstellt einen Zufallsstring mit der Länge $length
 function randStr($length)
 {
  # Mögliche Zeichen
  $chars="ABCDEFGHJKLMNPRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789";
  $text="";
 
  while(strlen($text) < $length)
  {
   # Eins der möglichen Zeichen an den String anhängen
   $text .= substr($chars, (mt_rand() % (strlen($possible))), 1);
  }
  
  return($text);
 }
 
 # Zufälliger Text mit der Länge 5
 $text = randomString(5);
 # String in Session-Variable speichern
 $_SESSION['captcha'] = $text;
 
 # Grafik generieren
 
 # es wird ein Bild erstellt
 header('Content-type: image/png');
 
 # Hintergrundbild laden (Pfad bei Bedarf anpassen)
 $bild = ImageCreateFromPNG('captcha.png');
 # Schriftfarbe, hier Weiß, kann angepasst werden
 $farbe = ImageColorAllocate($bild, 255, 255, 255);
 # Schrift laden (Pfad bei Bedarf anpassen)
 $schrift = realpath("font.ttf");
 # Schriftgröße
 $schriftsize = 25;
 # Winkel zufällig erzeugen
 $winkel = rand(0,5);
 # Position zufällig erzeugen
 $posX = rand(5,30);
 $posY = 35;
 
 # Text in das Bild schreiben
 imagettftext($bild, $schriftsize, $winkel, $posX, $posY, $farbe, $schrift, $text);
 # Bild ausgeben
 imagepng($bild);
 
 # Bild aus dem Speicher löschen
 imagedestroy($bild);
?>

Dieses Script wird nun unter captcha.php gespeichert. In diesem Fall heißt die Schriftart 'font.ttf' und das Hintergrundbild 'captcha.png'. Bei Abweichungen muss dies im Script geändert werden.

Das HTML-Formular mit Captcha könnte nun so aussehen:

<form action="foo.php" method="post">
 <img src="captcha.php" alt="Captcha">
 <input type="text" name="captcha">
</form>

Der Pfad zum Captcha muss wahrscheinlich auch angepasst werden.

Nun kann man mit PHP die Daten einfach überprüfen:

<?php
 if($_POST['captcha'] != "" && $_POST['captcha'] == $_SESSION['captcha'])
 {
  //Das Captcha stimmt, der Aufruf stammt wahrscheinlich nicht von einem Spambot
 }
?>

Es muss einfach nur überprüft werden, ob das Captcha und der eingegebene Text übereinstimmen. Wichtig ist außerdem, dass überprüft wird, ob das Captcha leer ist. Denn wenn ein Spambot einen Aufruf sendet, ohne jemals das Formular geöffnet zu haben und das Feld "captcha" leer lässt, ist sowohl das Captcha als auch der eingegebene Text leer und der Bot würde akzeptiert werden.

Ich hoffe, dass die Verwendung von Captchas das Internet in Zukunft von ein wenig Spam befreien wird.