Spamfreies, komfortables Kontaktformular

Auf itkb.ch sollte ein Kontaktformular vorhanden sein, dass folgende Anforderungen erfüllt:

  • (möglichst) Spamfrei
  • kein externen Inhalte (Datenschutz)
  • barrierefrei, keine Captcha-Codes
  • komfortabel

Dabei wurde in Kauf genommen, dass das Formular selber programmiert werden muss und es wurden keine fertigen Scripte/Widgets, ... verwendet (was aber nicht heisst, dass es nicht Scripte gibt, die diesen Schutz bieten).

Um das Ziel zu erreichen wurden drei Massnahmen getroffen, die nachfolgend noch genauer erklärt werden:

  • URL Honeypot
  • Formular-Timestamp
  • keine Kopie an Absender

URL Honeypot

Man liest im Netz immer wieder, dass ein URL Honeypot eine einfache und sehr effektive Massnahme ist. Dabei erstellt man einfach ein weiteres Eingabefeld mit dem Namen "url" und blendet es via Javascript vom Browser aus. Damit das Formular barrierefrei ist, darf man ruhig daneben schreiben, dass dieses Feld zwingend leer belassen werden muss.

<div id="hfijefnd">
<input type="text" name="url" /> Feld unbedingt leer lassen
</div>
<script type="text/javascript">
document.getElementById('hfijefnd').style.display = 'none';
</script>

Trotz anfänglicher Skepsis überzeugt der URL Honeypot komplett und filtert auf dieser Webseite mehr als 98% aller Spam-Anfragen absolut zuverlässig aus und führt zu keinerlei "false positives", also echten Kontaktanfragen, die dadurch irrtümlich gefiltert werden. Dadurch ist der URL Honeypot eine Empfehlung.

Wichtig: Formulare, die durch den URL Honeypot blockiert werden, werden bei mir in einer Logdatei mit Zeitpunkt, IP, Absender und Betreff geloggt um die Erfolgsquote festzustellen, der Benutzer sieht jedoch keine Fehlermeldung sondern erhält die normale Bestätigungsseite, dass seine Anfrage versendet wurde. So wird er nicht aktiv auf seinen Fehler aufmerksam gemacht.

Formular-Timestamp

Eine weitere einfache Möglichkeit stellt ein Formular-Timestamp dar. Ich erzeuge also beim Aufruf der Formular-Seite eine Browser-Session und speichere den aktuellen Timestamp ab. Wenn das Formular dann abgesendet wird prüfe ich diesen Timestamp auf Plausibilität, d.h. er muss vorhanden sein (ansonsten würde man das Formular direkt über ein Script absenden, ohne es vorher aufzurufen), muss mindestens 10 Sekunden alt sein (schneller füllt niemand ein Formular aus) und darf maximal 5h alt sein (länger hat man kein Browser-Formular geöffnet).

Kontaktformular:


session_start();
$_SESSION['contact_timestamp'] = date('U');

Script, welches Mail versendet:


session_start();
if (
  (isset($_SESSION['contact_timestamp']))
  and ($_SESSION['contact_timestamp'] < (date('U')-10))
  and ($_SESSION['contact_timestamp'] > (date('U')-60*60*5))
) {
  unset($_SESSION['contact_timestamp']); // Timestamp wieder entfernen
  // alles OK, Mail versenden
} else {
  // Fehler, ignorieren
}

Auch hier stelle ich auch bei fehlerhaftem Timestamp dem Benutzer keine Fehlermeldung dar und protokolliere Anfragen wieder. Dadurch konnte ich bis jetzt jene Anfragen, welche den URL Honeypot passiert haben zuverlässig rausfiltern. Wie viele URL-Honeypot-Anfragen auch durch den Timestamp hätten gefiltert werden können kann ich nicht sagen, da ich nach dem URL Honeypot keine weiteren Checks mehr vornehme und der Timestamp erst zweiter Stelle geprüft wird. Auch mit dieser Variante hatte ich bis jetzt noch keinen "false positive", schliesse aber nicht 100%ig aus, dass nicht künftig mal jemand ein echtes Formular in weniger als 10 Sekunden ausfüllt.

keine Kopie an Absender

Ich verzichte bei dem Kontaktformular auf itkb.ch darauf, dem Benutzer die Möglichkeit zu bieten eine Kopie der Anfrage zu erhalten. Dadurch wird das Formular für Spammer deutlich weniger attraktiv, da er seine Spam-Nachrichten nur an den Webmaster der Seite senden kann. Könnte er eine Kopie an den Absender senden könnte er eine beliebige Mailadresse als Absende-Adresse eintragen, welche dann auch eine Kopie der Spam-Nachricht erhält und so Drittpersonen über dieses Kontaktformular belästigen.

Die fehlende Möglichkeit einer Kopie an den Absender stellt einen minimalen Komfortverlust für den Benutzer dar, macht das Formular aber deutlich weniger attraktiv für Spammer. Wie viele Anfragen sich dadurch verhindern liessen lässt sich natürlich nicht beziffern.

Fazit, Fragen und weitere Infos

Durch diese einfachen Schritte konnte ich bis jetzt Spam-Mails via Kontaktformular über diese Webseite komplett verhindern. Der Programmieraufwand hielt sich dabei in Grenzen und benötigt nur wenige Zeilen Javascript- und PHP-Code. Das gesamte Kontaktformular (Formular, Fehlerchecks, E-Mail Versand, Bestätigungsseite) benötigt ca. 170 Zeilen Code, dafür entfällt rund die Hälfte der Zeilen auf das HTML-Formular und den Javascript-Code für Pflichtfeld-Check (lesefreundlich gecoded). Der Zusatzaufwand dieser Massnahmen beträgt ca. 30 Zeilen Code und könnte ohne Logging nochmals deutlich reduziert werden.

Bei Fragen stehe ich gerne zur Verfügung, eine Möglichkeit, das Kontaktformular auf itkb.ch auszuprobieren (auf der Kontaktseite ist aber auch eine E-Mail Adresse aufgeführt). Ich verzichte an dieser Stelle auf fixfertigen Code und stelle nur beispielhafte Code-Ausschnitte dar.