von | Blog, PHP

Viele Online-Formulare wurden durch die Nutzung von Captchas als Schutz vor Spam extrem benutzerunfreundlich. Im Beitrag “Formular-Spam vermeiden ohne Captchs mit Honeypot” hatte ich bereits eine Methode zur Spamvermeidung erklärt. Eine weitere Methode funktioniert mittels einfacher Zeitmessung. Natürlich können beide Methoden kombiniert werden.

Das Prinzip fusst aus der Tatsache, dass die meisten Spam-Anfragen von Bots, also automatisch ausgeführt werden. Dies geschieht naturgemäß sehr schnell, die Verweilzeit auf der Seite mit dem Formular ist also sehr gering. Wenn die Verweilzeit also zu kurz oder zu lang (dazu kommen wir später) ist, können wir davon ausgehen, dass es sich um Spam handelt.

Zunächst sollten die folgenden Definitionen vorgenommen werden:

define ('Startzeit', time());   // -------------------- Startzeit des Scripts setzen, NACH Absenden des Formulars
define ('MinVTime', 10);        // -------------------- Minimale Verweildauer auf Formularseite
define ('MaxVTime', 36000);     // -------------------- Maximale Verweildauer auf Formularseite

Die Werte für die minimale Verweildauer ist dabei formularabhängig und sollte ausprobiert werden. Ich würde mit einer höheren Verweildauer anfangen und diese dann ggf. sukzessive heruntersetzen, damit keine echten Anfragen verloren gehen.

Als nächstes sollte im Anfrageformular die Startzeit als verborgenes Feld gespeichert und mit dem Zeitwert gefüllt werden:

<?php $akttime = ($err) ? $_POST['date'] : time();            // ----- Aufrufzeit des Scripts ermitteln ?>
...
<form name="form1" method="post" action="">
  <input name="date" type="hidden" value="<?php echo $akttime; ?>" />
  <!-- Hier stehen die beötigten Formularfelder -->
</form>

Warum fülle ich das Hidden-Field nicht einfach mit time() fragt sich vielleicht manch geneigter Leser. Wenn das Formular über keine Eingabekontrollen bzw. Pflichtfelder verfügt, funktioniert dies problemlos. Die Bedingte Zuweisung in Zeile 1 kommt bei einer Falscheingabe zum Tragen, also wenn das Formular abgeschickt wurde und ein Fehler entdeckt wurde $err == true. In diesem Fall soll der Zeitwert vom ersten Aufruf genommen werden, ansonsten steigt die Chance, dass ein menschlicher, potentielle Kunde, die Anfrage getätigt hat und z.B. nur noch ein fehlendes Kreuzchen korrigiert. Die Verweilzeit würde dann wahrschenlich sehr kurz sein, obwohl es sich um keine Spamanfrage handelt.

Wie wird die Verweilzeit geprüft? In der Nachbearbeitung des Formulars wird der Wert $_POST['date'] von Startzeit subtrahiert. Das Ergebnis ist die Verweilzeit.

// ------------------------------------------------------------------------ Spam detection -> Verweilzeit
if (!isset($_POST['date']) or !is_numeric($_POST['date']) ) $spam = true;
else { $vZeit = Startzeit - intval($_POST['date']); }  // ----- Verweilzeit berechnen
if ($vZeit < MinVTime) $spam = true;
if ($vZeit > MaxVTime) $spam = true;

Wie kann es eine zu lange Verweilzeit geben, ein Spambot ist doch extrem schnell?
Richtig, aber es gibt zwei Möglichkeiten für einen Spambot, ein Formular abzusenden. Die erste ist, dass die Formularseite genauso aufgerufen wird, als wäre der Bot ein Browser. Meist wird sogar eine Browserkennung genutzt. In diesem Fall werden die Inhalte der Hidden-Felderbeim Seitenaufruf übernommen, die Felder werden ausgefüllt und das Formular wird abgeschickt. In diesm Fall haben wir eine Anfrage mit geringer Verweilzeit.

Die zweite Möglichkeit ist aber, beim ersten Besuch der Seite die vorhandenen Felder zu analysieren und zu speichern. In diesem Fall werden die Inhalte der Hidden-Felder mitgespeichert. Die eigentliche Spamanfrage erfolgt dann durch einen Aufruf der Formular-URL mit Übergabe der gewünschten Feldinhalte. Die Hidden-Fields behalten dann Ihre eigentlichen Inhalte (also den ursprünglichen Zeitstempel) oder sie werden mit zufälligen Werten gefüllt.

Aus diesem Grund wird auch auf eine zu lange Verweilzeit und einen nicht numerischen Wert geprüft.

Vielen Dank für’s Lesen!

 

Kommentare sind geschlossen.