jspit.de
Impressum

AntiSpam - PHP form class

Software: AntiSpam - PHP form class LGPL-Logo
Datei: class.antispam.php Download
Version: 1.0 Beta

Ziel

Ziel ist es ein Formular-Spamschutz zu realisieren, der ganz auf überflüssige zusätzliche Nutzereingaben (Captcha, Rechenaufgaben...) verzichtet und damit auch für barrierearme Anwendungen nutzbar ist. Einige Beispiele von Spam die geblockt werden:
  1. Die maschinelle "Bearbeitung von Formularen" durch Bots (scheitern am Zeitrahmen)
  2. Das Zuschicken von "ausgefüllten" Formularen (scheitern an der TAN-Nummer)
  3. Das übermäßige Zusenden von Formularen eines Absenders (scheitern an IP-Sperre)
  4. Das wiederholte manuelle Absenden ein und derselben Formulare

Konzept und Funktion

Mit der ersten Anforderung des Formulars wird eine zufällige TAN generiert, die in einem Hidden-Feld übermittelt und zusammen mit einem Zeitstempel auf dem Server gespeichert wird. Nach dem Absenden des Formulars wird auf dem Server überprüft, ob eine gültige TAN im Hiddenfeld geliefert wurde. Wenn ja, wird zusätzlich überprüft ob der Zeitstempel in einen definierten Zeitrahmen liegt und die Anfragen von derselben IP-Adresse eine bestimmte Anzahl/Zeiteinheit nicht überschreitet. Ist alles ok wird das Formular als gültig angenommen und die TAN als verbraucht markiert. Eine höhere Erkennungsrate wird erreicht, wenn Javascript auf dem Client aktiv ist. Zusätzlich zur TAN wird eine dynamisch generierte Javascript-Funktion ausgeliefert, die in das Formular einzubinden ist. Mit dem Absenden des Formulars wird die TAN mit der (zufälligen) Funktion verschlüsselt. Auf dem Server wird das verschlüsselte Ergebnis verglichen. Sessions werden nicht verwendet.

Benutzung

Für einen einfachen Antispam-Schutz mit der PHP Antispam Class sind nur wenige Zeilen PHP-Code notwendig, wenn auf die Defaulteinstellungen der Klasse zurückgegriffen wird.
Beispiel:
require 'class.antispam.php'; //Class einbinden
$asp = new AntiSpam(); //Object erzeugen
$tan = $asp -> GetTAN('tan'); //tan erzeugen
$spam = ($tan === false);

Für die Erkennung ob ein ausgefülltes Formular vorliegt oder ein leeres Formular angefordert wird, kann isFormFilled() benutzt werden.
Beispiel:
if($asp -> isFormFilled()) {
	//Formular empfangen
	if($spam) echo "Sorry, die Nachricht wurde als Spam klassifiziert.";
	else { 
	//eigene Formularfelder prüfen
	}
}

Werden im Formular in den eigenen Feldern Eingabefehler erkannt und möchte man dem Nutzer das Formular erneut zuschicken um ihm die Möglichkeit einer Korrektur zu bieten, dann muss die bereits als verbraucht markierte TAN wieder gültig gesetzt werden. Dafür stellt die Klasse die Funktion SetTANvalid() zur Verfügung.
Beispiel:
if($eingabefehler) $asp -> SetTANvalid();

Im Formular wird ein zusätzliches Input-Element vom Typ hidden benötigt, dessen Name identisch mit dem Parameter des GetTAN-Aufrufes sein muss. Als value wird die generierte TAN übergeben.
Beispiel:
<form action="" method="post">
<input type="hidden" name="tan" value="<?php echo $tan;?>">

Bei der Variante mit Javascript kann die Erkennungsrate von Spam noch erhöht werden. Beim Nutzer (Client) muss dafür Javascript im Browser aktiviert sein. Im serverseitigen Script werden dafür einige zusätzliche Zeilen notwendig. Vorzugsweise im <head> unserer Seite ist nach dem Aufruf von GetTAN unser dynamisch generiertes Javascript auszugeben:
echo $asp -> javascriptcode;

Die im Script definierte Funktion pj_antispam_mcr verschlüsselt die TAN im Hidden-Feld, und das für jedes Formular anders. Beim Absenden des Formulars müssen wir nur dafür sorgen, dass die Funktion pj_antispam_mcr zur Ausführung kommt.
Beispiel:
<form action="" method="post" onsubmit="pj_antispam_mcr();return true;">
<input type="hidden" name="tan" value="<?php echo $tan;?>">

Mit dem Attribut useJS und der Methode isJSaktiv kann die Javascript-Variante flexibel gestaltet werden. Mehr dazu in der Beschreibung der Attribute und Methoden.

Attribute

Das Verhalten der Klasse kann durch eine Reihe Eigenschaften den eigenen Bedürfnissen angepaßt werden. Die Attribute werden hier kurz tabellarisch dargestellt.
NameDefaultwertBedeutung
maxformtime1200 max. Zeit in Sekunden (default 20 Min) für das Ausfüllen des Formulars. Wird diese Zeit überschritten, wird das Formular als Spam klassifiziert.
minformtime10 min. Zeit für das Formular. Wird das Formular schneller abgeschickt, wird ein Automatismus vermutet und das Formular als Spam klassifiziert.
maxIPs5 max.Anzahl an Formularen von derselben IP innerhalb der Zeitspanne liveTime (Default 1h).
liveTime3600 Lebensdauer der TANs in Sekunden, gleichzeitig Zeitspanne für die Zählung der IPs.
IpcountMode2 Bestimmt wie die IPs gezählt werden. 1=nur angeforderte Formulare, 2=ausgefüllte Formulare, 3=Alle.
GroupName"" Name der Formulargruppe.Ist keine Gruppe angegeben, wird intern für jeden tan-Namen eine Gruppe gebildet. Alle Formulare einer Gruppe werden gleich behandelt. Sollen Formulare aus verschiedenen Ordnern in einer Gruppe organisiert werden, ist den Namen ein gültiger Pfad voranzustellen. Beispiel: $asp -> GroupName = "../org/Kontakt"; Hinweis: Für das Beispiel wird eine Datei Kontakt.dat in ../org/ angelegt, in den Verzeichnissen müssen die entsprechenden Rechte bestehen.
useJSfalse Bei true wird Javascript beim Client gefordert. Es ist zusätzlicher PHP-Code notwendig. Wird der dyn.generierten JS-Code beim Client nicht ausgeführt, dann wird mit useJS=true das Formular als Spam klassifiziert. Mit useJS=false führt dies nicht automatisch zur Spamklassifizierung. Mit der Methode isJSaktiv kann dann festgestellt werden, ob der Code ausgeführt wurde. Wird kein JS-Code mitgeliefert, ist useJS auf false zu setzen.
javascriptcode - Enthält den dyn.generierten JS-Code, der in den Code einzufügen ist. Steht nach dem Aufruf der Methode GetTAN zur Verfügung.
NamejsFunctionpj_antispam_mcr Name der Funktion im dyn.generierten JS-Code. Nur in speziellen Fällen ist es notwendig einen anderen Namen zu wählen.
spamtyp - Enthält eine Zahl > 0, sofern das Formular als Spam klassifiziert wurde und 0 wenn das Formular nicht als Spam klassifiziert wurde.

Methoden

NameBedeutung
GetTAN GetTAN(Name) liefert bei Anforderung des Formulars eine zufällige TAN. Als Parameter ist der Name des hidden-feldes im Formular anzugeben. Dieser muss einmalig sein. Wird ein gefülltes Element mit den Namen 'tan' vorgefunden, wird dessen Wert mit der gespeicherten TAN verglichen. Bei einer Spamerkennung ist der return-Wert false.
SetTANvalid Setzt eine bereits als verbraucht markierte TAN wieder gültig. Wird ein gefülltes Formular empfangen, wird dessen TAN sofort als verbraucht markiert und kann nicht mehr benutzt werden. Werden Eingabefehler in den eigenen Feldern des Formulars erkannt und möchte man den Nutzer die Möglichkeit einer Korrektur bieten, dann muss die TAN wieder gültig gesetzt werden. Speziell dafür stellt die Klasse die Funktion SetTANvalid() zur Verfügung.
isFormFilled Die function isFormFilled() liefert nach Abarbeitung von GetTAN() eine Information true/false ob das Hidden-Feld im Formular ausgefüllt ist oder nicht. Das Ergebnis ist somit false bei Anforderung eines Formulars, true bei gesendeten Formularen. Die Nutzung von isFormFilled ist optional, der Nutzer kann auch wie gewohnt seine POSTs für die Auswertung heranziehen.
getSpamDescription Die function getSpamDescription() liefert nach Abarbeitung von GetTAN() zum spamtyp eine Beschreibung.
getIPcount Liefert eine Information zum Stand des IP-Zählers.
isJSaktiv Ist im Code der von der Klasse generierte Javascriptcode und in die Form die notwendigen Funktionsaufrufe eingefügt worden, dann liefert isJSaktiv() nach Abarbeitung von GetTAN() eine Information true/false ob der Javascriptcode abgearbeitet wurde.

Eine Überprüfung der Formularfelder auf sinnvolle Inhalte bietet einen zusätzlichen Schutz und sollte auch bei Nutzug dieser Klasse nicht unterbleiben. Ansatzweise ist eine solche Überprüfung im Beispiel simple_antispam.php zu sehen.