Kontaktformular

PHP-Kontaktformular mit Abwehr gegen Bots/Spam

Da ich auch eine Seite ohne CMS pflege, stand ich vor etwa anderthalb Jahren vor dem Problem, wie ein Kontaktformular zu erstellen ist, dass gegen Bots gesichert ist, die das Mailpostfach dahinter mit Müll zuspammen.

Das ganze sollte auch bei Kommentar-Eingaben gut funktionieren, wenn jemand soetwas selber baut.

Mein erster Gedanke war so ein Rechen- oder Bilderkennungs“dings“ (Capatcha) einzubauen, wie weit verbreitet. Da ich auf google oder andere „einfache Lösungen“ verzichten wollte, die nebenbei (bzw. hauptsächlich zur Finanzierung) deren künstliche „Intelligenz“ trainieren oder korrigieren, ging ich auf die Suche nach halbwegs einfach einzubauende Lösungen. Einfache Plugins wie in einem Blog etc. standen nicht zur Verfügung, da kein CMS vorhanden ist.

Irgendwo (leider weiß ich nicht mehr wo genau, sonst wäre hier ein Link) Im Netz stieß ich in einem PDF das laut Fußzeile von homepage.t-online.de kommt (leider finde ich den Link dahin nicht mehr), auf eine schöne Idee: dem Bot ein Feld „zu zeigen“, das der menschliche Benutzer nicht sieht, der Bot aber ausfüllen will. Der Bot „guckt“ sich die Seite nicht wie ein Mensch an, sondern ließt den Quelltext. Und diesen Unterschied zum menschlichen Nutzer macht sich diese Idee zu Nutze:

Kontaktformular
So sieht das menschliche Auge das Kontaktformular

Der Mensch füllt die Felder aus, die sie/er sieht: Name, Absender-Mail und einen Nachricht. Der Bot füllt auch das zusätzliche Feld aus (Bots füllen immer alle Felder mit ihrem Spam!). Vor dem Versand prüft das Script, ob alle nötigen Felder gefüllt ist – vergisst die Person z.B. eine Absender-Mail gibt es eine Warnung.

Und ist das unsichtbare Feld ausgefüllt, wird die Spam-Mail verworfen und man landet auf der 404-Seite. Daraus lernt die BOT-Farm vielleicht sogar, dass das Kontaktformular gar nicht funktioniert.

Ich vermute leider, diese Lösung könnte Probleme beim barrierefreien Nutzung machen. Vielleicht sollte ich doch noch eine getrennte Warnung ausgeben.

Schritt 1: Eine „Falle“ für den Bot aufstellen.

Ich habe mich für das tatsächlich oft existierende „Bestätige deine Mailadresse“-Feld entschieden. Also an passender Stelle im Quelltext eine Kopie des Absender-Mail-Feldes erstellt und ähnlich benannt.

So sieht das echte Mailfeld aus:

<div class="field">
<input type="text" name="email" placeholder="Ihre Mailadresse" data-rule="email" data-msg="Bitte eine Mailadresse angeben" />
</div>

Und direkt danach kommt das neue Feld:

<div class="field require">
<input type="text" name="mail2" placeholder="Bitte noch einmal ihre Mailadresse angeben" data-rule="email" data-msg="Bitte noch einmal ihre Mailadresse angeben" />
</div>

Der div-Klasse habe ich nur ein „require“ hinzugefügt. Damit konnte ich im CSS eine Option ergänzen, mit der dieses Feld für den Browser unsichtbar gemacht wird. Begriff wie „Honeypot“, „Bot“ etc. habe ich vermieden und es ordentlich benannt und möglichst unauffällig eingebaut. In der Recherche zu diesem Beitrag stieß ich auch auf Anleitungen, die noch viel mehr CSS Tricks basteln mussten, damit die Bots die Schutz-Mechanismen nicht erkennen. Teilweise waren da die Felder auch ungünstig benannt, was schneller zu erlernen und von den Bots zu umgehen ist.

Zuerst habe ich mir das neue Feld noch ganz normal anzeigen lassen, um die Funktion zu testen.

Schritt 2: extra Schleife im Mailversand

Im PHP-Mail-Script habe ich nur eine extra Schlaufe gelegt, bevor dort die Eingaben aus den anderen Felder gezogen werden. Dort habe ich einen kurzen Block eingefügt, der prüft, ob etwas im „Honeypot“-Feld steht, dann wird der Prozess gestoppt:

//Dummy-Feld - kein Versand
if ($_POST["mail2"] != '' ) {
  header("Location: " . $fehlerSeite);
die ();
}
else {

Zusätzlich habe ich noch eine Prüfung eingebaut, dass bestimmte Felder ausgefüllt sein müssen: Mailadresse, Betreff und Text. Eine einfache Prüfung, dass die Felder nicht leer sind sollte auch die Bots vermeiden, die nur einzelne Felder ausfüllten und deshalb weiterhin durchkamen:

if(empty($_POST['email']) OR empty($_POST['message']) OR empty($_POST['subject']) ) {
  header("Location:" . $fehlerSeite);
die ();
}
else {

Danach folgt der eigentliche Mailversand.

Alternative Reihenfolgen/Abfragen:

In dieser Anfrage könnte die Abfrage statt „empty“ auch mit „== ‚ ‚“ gearbeitet werden, was in etwa das gleiche bedeutet.

In der ersten Abfrage könnte statt ‚!=‘ (nicht leer) auch anders herum gearbeitet werden. Zum Beispiel nach der Abfrage ob die Mail, Nachricht und Betreff nicht leer sind den Mailversand mit mit der Option wenn „if ‚mail2‘ leer“ beginnen und dann zum Mailversand schreiten. Dann müsste die else Option am Ende aber auf eine Fehlerseite oder in eine Fehlermeldung leiten.

Da es so funktionierte, habe ich es dabei belassen. In der Quelle hieß der Vorschlag übrigens noch etwas anders, wollte bei mir aber nicht funktioneren:

<?php
if (isset($_POST['email'])) {
echo "Ihre Beitrag wurde als Spam identifiziert. Bitte überprüfen Sie Ihre Eingaben.";
die ();
}
else {

Schritt 3: Feld im CSS „unsichtbar“ machen

Damit nun die Nutzer der Seite das Feld nicht ausfüllen, habe ich es mit einer ergänzenden Zeile im CSS für das menschliche Auge unsichtbar gemacht. Einfach direkt nach den eigentlichen Eigenschaften des Objektes für die zusätzliche Definition (im Beispiel „require“) „display:none“ hinzufügen:

form#contactform .require {
	display:none;
}

In anderen Anleitungen heißt es teilweise, dass es selbst so nicht richtig funktioniert hat, statt dem hidden field wurde dann mit überlappenden divs gearbeitet die der Mensch nicht sieht, für den Bot aber nicht offensichtlich ausgeblendet ist.

Schritt 4: Ruhe im Postfach

Seitdem ist Ruhe mit Spam über das Kontakt-Formular. Spätestens als ich nach meiner Fehleinschätzung, dass die Bots immer alle Felder füllen wollen, noch die Abfrage nach „Pflichtfeldern“ eingefügt habe war das der Fall.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.