Kampf dem Spam: Spamfreies Gästebuch
Vorgehensweise von Spambots
Ein Spambot geht im Regelfalle nach einem bestimmten Muster vor. Er hangelt
sich über Verweise von Seite zu Seite und schaut dabei nach etwaigen
Formularen. Findet er eines, so liest er es ein, analysiert es und speichert
sowohl die Adresse der betreffenden Seite als auch das Formular für weitere
Verwendung.
Sowie Spam verteilt werden soll, werden die zuvor gespeicherten Formulare
verwendet, um diesen digitalen Müll zu verbreiten. Dazu werden normalerweise
eine Mailadresse mit gültigem Format (wenngleich sie oftmals entweder ungültig
ist oder jemandem gehört, der nicht der Spammer ist), ggf. eine Homepage, ein
Betreff sowie die zu übermittelnde Nachricht eingetragen. Da hier kein Mensch
am Werke ist, sondern ein Programm den Vorgang automatisiert, geht dies binnen
kürzester Frist vonstatten. Der einzige Flaschenhals ist hier die Latenzzeit
des Internets.
Operation Honigtopf
Genau dieses Verhalten der Spambots kann man hervorragend gegen sie wenden. Sie müssen dazu einfach ein oder zwei zusätzliche Eingabefelder in das Formular einbinden, die hier jedoch keine Daten entgegennehmen, sondern stattdessen den Bot auf eine falsche Fährte locken sollen. Dazu ist es erforderlich, daß sie passend benannt werden, damit der Bot auf diese reagiert.
Wenn Ihre Falle auf eine Mailadresse gemünzt werden soll, dann benennen Sie das
Feld bitte passend (z. B. mail,
email o. ä.) und setzen einen dazu passenden
erklärenden Text, damit es für den Bot interessant wird.
Das Formularfeld sähe in diesem Fall wie folgt aus:
Dann fügen Sie noch Folgendes in Ihr CSS ein:
Es ist immens wichtig, daß Sie dieses Feld per CSS ausblenden, anstatt es als
type="hidden" zu definieren, da so
versteckte Felder sonst von den Bots 1:1 übernommen werden und Ihre Falle so
keinen Effekt hätte. Durch diese Ausblendung per CSS erscheint das Eingabefeld
als reguläres Eingabefeld und wird vom Bot beachtet.
Doch Vorsicht! Definieren Sie diese Stilinformation
nicht direkt im Eingabefeld, sondern erzeugen Sie eine Klassendefinition in
einer externen CSS-Stildatei, die Sie in das Dokument einbinden, und
anschließend setzen Sie lediglich die betreffende Klasse in einem Container,
der das auszublendende Eingabefeld umgibt, um es verschwinden zu lassen. Das
verhindert, daß der Bot möglicherweise einen Zusammenhang zwischen der
Ausblendung und dem Schwindel-Eingabefeld herstellt.
Damit erreichen Sie Zweierlei: In einem normalen, CSS-fähigen Browser wird
dieses Eingabefeld nebst Label für den Anwender ausgeblendet, so daß es für
diesen nicht zu sehen ist. Gleichzeitig wird das Feld in einem Browser, der
CSS nicht interpretiert (z. B. der Textbrowser Lynx), so ausgezeichnet, daß der
Anwender sofort weiß, daß er hier nichts eintragen darf. Dadurch, daß der
beschreibende Text als Label dem Eingabefeld direkt zugeordnet wird, können
Hilfsmittel für Sehbehinderte diese
Information an den Benutzer weiterleiten, damit auch diese Bescheid wissen.
Somit ist das Kriterium der Barrierefreiheit hier erfüllt.
Daneben müssen Sie natürlich noch ein Feld anlegen, das die Mailadresse dann
auch tatsächlich aufnimmt. Dieses können Sie ganz nach eigenem Gusto benennen,
und der Name muß noch nicht einmal auf den Zweck des Feldes schließen lassen –
was insbesondere dann interessant wird, wenn es sich um ein Pflichtfeld handelt
(dies sollte bei einer Mailadresse immer der Fall sein). Somit stellt das echte
Feld einen zusätzlichen Stolperstein für Spambots dar, da sie es i. d. R. leer
lassen, wenn sie nicht erkennen können, worum es sich handelt.
Darüber hinaus ist es immens wichtig, daß Sie Pflichtfelder passend markieren,
sowohl im Label des Feldes als auch im Eingabefeld selber. Ersteres
funktioniert immer, für Letzteres brauchen Sie einen Dokumenttyp, der
ARIA unterstützt.
Dabei sollten Sie jedoch nicht den Fehler machen, diese Felder gleich im
XHTML-Quelltext als Pflichtfelder zu markieren, sondern dies geschieht am
besten über ein JavaScript. Heutzutage können Hilfsmittel für Sehbehinderte
durchaus mit JavaScript umgehen, so daß die Veränderung des Labels und das im
Eingabefeld gesetzte ARIA-Attribut von
diesen wahrgenommen werden. Spambots werden diese Modifikationen jedoch nicht
bemerken, da sie nicht mit einer JavaScript-Engine ausgestattet sind: Der Bot
würde sonst schlichtweg zu klobig.
Zudem ist es wichtig, daß Sie das verarbeitende Skript so präparieren, daß es
Ihre Fallen überprüft. Dazu ist es vollkommen ausreichend, daß Sie überprüfen,
ob etwas in Ihre Fallen eingetragen wird. Sowie Sie hier etwas vorfinden,
wissen Sie, daß etwas faul ist, und können den Versuch abweisen. Wird dieser
Test bestanden, sind auf jeden Fall weitere Tests erforderlich, denn diese
Fallen können den selten vorkommenden manuellen Spam leider nicht abwehren.
Hier sind dann andere Methoden notwendig.
Eine einfache Überprüfung könnte beispielsweise wie folgt aussehen:
Fallen wie diese können Sie an x-beliebiger Stelle in Ihrem Formular
unterbringen, sie sollten jedoch zum Kontext passen. Wenn Sie beispielsweise
eine Falle über die Mailadresse aufbauen, so sollten Sie diese in der Nähe des
echten Eingabefeldes unterbringen, da zu weit abgesetzte Felder Argwohn
erwecken könnten und zukünftig von Spambots ignoriert werden, wodurch diese
Falle ihre Wirkung verliert.
Zudem muß die Mailadresse nicht die einzige Stelle sein, an der Sie
Stolperfallen ausbringen können. Je nach Verwendungszweck des Formulars ergeben
sich meist weitere Möglichkeiten für zusätzliche Stolperfallen, die allesamt
ähnlich konstruiert werden wie die für die Mailadresse.
Mit diesen einfachen Mitteln läßt sich schon mal der Großteil des Spams ausfiltern, so daß weitere Tests erst gar nicht bemüht werden. Bei dem, was noch übrig bleibt, können Sie gerne genauer hinschauen, ohne daß der Prozessor großartig strapaziert wird.
nach obenPlausibilitätsprüfungen
Sowie Sie die Eingabe haben, sollten Sie auf jeden Fall einige
Plausibilitätsprüfungen durchführen. So werden in einzeilige Felder manchmal
mehrzeilige Daten eingetragen – dies ist jedoch für diese Felder nicht
gestattet, und Sie sollten die entsprechenden Nachrichten daher abweisen.
Darüber hinaus sollten Sie weitere Plausibilitätsprüfungen durchführen, z. B.
ob sowohl die eingegebene Mailadresse als auch die Adresse der Homepage ein
gültiges Format haben und die angegebenen Server existieren. Zudem haben Sie
hier die Möglichkeit, die Servernamen wiederum gegen eine DNSBL zu überprüfen.
Manche Anbieter von Schwarzen Listen stellen solche bereit, in die Domainnamen
anstatt IP-Adressen eingetragen sind, welche im Zusammenhang mit Spam stehen.
Nachrichten, die problematische Domains enthalten, können so ebenfalls
abgewiesen werden.
Zeitschranken setzen
Aber auch die Zeit können Sie für sich arbeiten lassen. Ein normaler Mensch
kann eine Nachricht unmöglich innerhalb von Sekundenbruchteilen verfassen. Da
Spammer jedoch ungeduldig sind und innerhalb kürzester Zeit möglichst viele
Spamnachrichten unterbringen wollen, werden viele von ihnen ein Formular
einlesen und gleich darauf die Nachricht einzutragen versuchen. Hier greift
eine Zeitschranke, die den Versuch kurzerhand abblockt, wenn die Eintragung zu
schnell erfolgen sollte. Ein Wert von zehn Sekunden ist hier i. d. R.
brauchbar.
Aber auch der gegenteilige Effekt kann eintreten, daß ein Formular genau einmal
eingelesen und dann wiederholt zum Eintragen von Spamnachrichten verwendet
wird. Zwar wird dies nur in sehr wenigen Fällen eingesetzt – genau genommen ist
mir bisher noch kein Versuch dieser Art untergekommen – aber wenn sie denn
auftreten, kann eine weitere Zeitschranke diese unterbinden: Kein Benutzer wird
mehr als eine halbe Stunde brauchen, um eine Nachricht zu verfassen, und wenn
doch, ist es höchstwahrscheinlich ein altes Formular, das jetzt wiederholt zum
Versenden von Spam verwendet wird.
Oftmals wird von Webseiten eine Session-ID gesetzt, um diese Zeitschranke zu
implementieren, zusammen mit dem ganzen Verwaltungsaufwand, um diese
Session-IDs in Datenbanken einzutragen, alte Einträge zu löschen, etc.
Allerdings geht dies auch einfacher: Sie legen einfach ein zusätzliches
Datenfeld in Ihrem Formular an, das Sie mit
type="hidden" definieren, so daß es zwar
vorhanden ist, einem Benutzer aber nicht angezeigt wird. Hier tragen Sie den
Zeitpunkt der Erstellung des Formulars ein.
Da das Datenfeld explizt als versteckt markiert ist, wird ein Spambot dieses
Feld unverändert lassen. Dabei ist es vollkommen unerheblich, wie Sie es
benennen. Auch können Sie den Spambot bezüglich der Zeitangabe zusätzlich
verwirren, indem Sie einen Offset in die Zeitangabe einrechnen, der nur Ihnen
bekannt ist und mit dem Sie eine Manipulation leichter feststellen können.
Zudem ist es auch nicht erforderlich, daß Sie diesen Wert verschlüsseln. Dies
spart erstens Rechenzeit, und zweitens wäre es sogar kontraproduktiv, wenn Sie
die Zeitangabe nutzen wollen, um die Spambots aufs Glatteis zu führen.
Wenn Sie Zeitschranken einsetzen, dann geben Sie unbedingt einen Hinweis an, daß ein automatisiertes Ausfüllen des Formulars zu Problemen führen kann. Zusätzlich können Sie auch einen Indikator angeben, ob das Formular einsatzbereit ist oder nicht, den Sie am besten mit JavaScript implementieren.
nach obenCheckbox als Türdrücker
Natürlich hat XHTML noch weitere Elemente im Arsenal, die es Ihnen erlauben,
zusätzliche Gemeinheiten einzubauen. So können Sie beispielsweise eine Checkbox
setzen (z. B. am unteren Ende des Formulars). Da Bots solche Checkboxen gerne
aktivieren, können Sie dieses Verhalten ebenfalls gegen sie einsetzen. Sie
gehen in diesem Fall genauso vor wie mit einem Schwindel-Eingabefeld, d. h.
Sie legen die Checkbox an, zeichnen sie mit Hilfe eines Labels so aus, daß ein
Benutzer sie nicht versehentlich anklickt, wenn er sie zu Gesicht bekommt, und
verstecken das ganze Konstrukt mittels CSS, genauso wie das
Schwindel-Eingabefeld.
Danach müssen Sie nur noch eine Abfrage für die Checkbox in Ihr Skript
einbauen, damit Sie alle Versuche, etwas mit markierter Checkbox einzutragen,
gleich abblocken können.
Wenn Sie besonders fies sein wollen, können Sie diese Definition auch umkehren
und die Checkbox als Pflichtfeld definieren, das Sie jedoch nicht direkt im
XHTML-Code notieren, sondern mittels JavaScript in das Formular einfügen und
mittels eines ebenfalls per JavaScript erzeugten Labels eine Erklärung setzen,
was vom Benutzer hier erwartet wird. Dadurch sehen Spambots dieses Eingabefeld
nicht und tappen prompt in diese Falle: Wird dieses Feld nicht übergeben, so
wurde die Checkbox nicht markiert, entweder weil man sie schlichtweg vergessen
hatte oder sie von einem Spambot nicht gesehen werden konnte.
In diesem Fall ist es jedoch zwingend erforderlich,
daß die Checkbox für den Benutzer sichtbar ist. Einziger Schönheitsfehler:
Browser, die kein JavaScript unterstützen, stehen vor verschlossener Tür.
In die Teergrube gerannt!
Allerdings sind Ihre Spamfallen nicht das Ende der Fahnenstange. Wenn Sie den
Spammern richtig auf die Nerven gehen wollen, können Sie das im Falle einer
Falscheingabe erreichen, indem Sie die Ausgabe des XHTML-Dokuments verzögern.
So können Sie, wenn Sie ein Problem entdecken, zunächst erst einmal eine Pause
erzwingen, bevor die ersten Daten an den Aufrufer zurückgegeben werden, und
auch wenn Sie mit der Ausgabe beginnen, haben Sie immer noch die Möglichkeit,
sie kleckerweise auszugeben, um somit möglichst viel Zeit in Anspruch zu
nehmen. Zeitverlust ist nämlich etwas, das Spammer überhaupt nicht mögen, und
auch wenn Sie bereits behelligt worden sind, sorgen Sie so dafür, daß der Bot,
der Sie gerade heimsucht, in dieser Zeit auf keinen anderen Server zugreifen
kann. Um dies zu erreichen, ist jedoch ein Griff in die Trickkiste vonnöten.
Folgender Code ist erforderlich, um die kleckerweise Ausgabe zu
bewerkstelligen:
Wichtig ist, daß Sie die Kopfdaten zunächst sofort an den Browser übergeben,
damit er keine Zeitüberschreitung signalisiert! Die Auslieferung des
eigentlichen Dokuments können Sie dann entsprechend verlangsamen.
Wenn Sie möchten, probieren Sie so eine
Teergrube doch mal aus! Aber Vorsicht! Der Ladevorgang dauert sehr lange!
Prinzipiell gibt es hierfür zwei verschiedene Varianten: Entweder bauen Sie den
XHTML-Code in einer Variable zusammen und geben diese Daten anschließend
zeitverzögert aus, oder Sie starten in Ihrem Skript einfach einen zweiten
Prozeß, der als Mittler zwischen der XHTML-Ausgabe und dem Webserver fungiert.
Hier wird die zweite Variante beschrieben, da sie mit einem Minimum an Aufwand
verbunden ist, wenn Sie ein bereits bestehendes Skript anpassen möchten. Sie
müssen dazu lediglich ein Dateihandle in die bereits bestehenden
print-Anweisungen einsetzen, anstatt sie komplett
umzuschreiben. Zusätzlich ergänzen Sie das Skript einfach um eine
fork-Anweisung und bauen eine Abfrage des
Rückgabewertes ein, da beiden Prozessen unterschiedliche Aufgaben zufallen.
Haben Ihre Spamfallen ausgelöst, öffnen Sie zunächst eine Pipe für die
Kommunikation zwischen den beiden Prozessen, die die Ausgabe übernehmen sollen.
Danach erzeugen Sie in Ihrem Skript mit der Anweisung
fork einen neuen Prozeß.
Jetzt haben Sie das Perlskript quasi dupliziert, und je nachdem, auf welcher
Seite Sie aus dem fork-Aufruf herauskommen, müssen
Sie unterschiedliche Codesequenzen ausführen, wenn Sie die Arbeit nicht doppelt
ausführen wollen. Das Indiz dafür ist der zurückgelieferte Wert der Funktion:
Null bedeutet, daß Sie im Kindprozeß gelandet sind, und ein Wert ungleich Null
markiert den Elternprozeß. Dies läßt sich in einer
if-Abfrage überprüfen.
Im Elternprozeß schließen Sie zunächst einmal das Handle für den Leser, da Sie
hier ausschließlich Daten ausgeben, und sowie das geschehen ist, schreiben Sie
Ihr XHTML-Dokument einfach in die Pipe. Sind Sie damit fertig, schließen Sie
auch das Schreibhandle und weisen den Elternprozeß an, auf den Kindprozeß zu
warten.
Währenddessen schließen Sie das Schreibhandle im Kindprozeß und schicken ihn
für eine halbe Minute schlafen, wodurch Sie bereits die Wartezeit für den
Aufrufer definiert haben. Schließlich kann man davon ausgehen, daß Sie es mit
einem Spambot zu tun bekommen, wenn Ihre Fallen auslösen, also kann man ihm
genauso gut die Zeit stehlen.
Ist die anfängliche Zeit um, so fangen Sie an, den XHTML-Code zeichenweise
auszugeben, wobei Sie zwischen einzelnen Zeichen eine Sekunde Pause lassen.
Dabei dauert die Zeit für die Übertragung etwa eine Sekunde pro übertragenem
Zeichen, und wenn das Dokument hinreichend lang ist, gehen mindestens mehrere
Minuten bis hin zu ein paar Stunden ins Land – und je länger das Dokument ist,
umso mehr Zeit stehlen Sie den Spammern.
Schließen Sie zum Ende des Kindprozesses das Lesehandle und beenden Sie ihn
zwingend mit der Anweisung
exit(0), da Sie sonst
außerhalb des Kindblocks wieder denselben Code ausführen wie im Elternprozeß.
Schlußfolgerung
Manchmal sind einfache Methoden ausgesprochen effektiv, insbesondere wenn man
sie richtig aufzieht. Im Vergleich zu einem
Captcha lassen sich diese Fallen einfach in den
XHTML-Code schreiben und fügen sich nahtlos in diesen ein. Die Auswertung
geschieht mittels einfacher Abfragen in dem Skript, das das Formular ohnehin
auswertet, ganz ohne Nutzer- oder Session-IDs, und zudem können Sie alles auf
Ihrem Server selbst regeln, ohne dritte Parteien einschalten zu müssen. Da
zudem alles in Textform vorliegt, kann man es problemlos darstellen lassen,
auch wenn man unter einer Sehschwäche leidet, da sämtliche Lesehilfen das
Dokument auswerten können und ihre Benutzer darauf hinweisen, womit sie es zu
tun bekommen.
Ein Captcha hingegen ist erstens nicht einfach einzubinden, da man zunächst
einmal etwas von einem anderen Server herunterladen muß, und wenn man so etwas
nicht selbst implementieren möchte,
muß man auf die Dienste Dritter zugreifen. Hier sind jedoch mehrere
Kommunikationspfade berücksichtigen: Sie müssen einmal das Captcha vom Server
des Anbieters herunterladen, damit es einem angezeigt wird. Da allerdings eine
Graphik eingebunden wird, stehen Leute mit Sehschwäche schon mal vor einem
Problem: Wie bitteschön erkennen, was da steht? Denn auch Leute mit gut
funktionierenden Augen haben so manches Mal schon ihre liebe Not mit den
Graphiken, wie sollen Leute mit Sehschwäche dann damit zurecht kommen?
Dann benötigt man zudem einen Kommunikationspfad von dem Server, der das
Formular bereitstellt, zu dem Server, von dem das Captcha stammt, um
feststellen zu können, ob die Eingabe überhaupt richtig war. Dazu bedarf es
eines ausgeklügelten Datenaustauschs, da das Captcha das, was in sein
Eingabefeld eingegeben worden ist, zuerst einmal an den Server übermittelt, der
es bereitgestellt hat. Danach muß das Skript, das das Formular auswertet, mit
dem Server, von dem das Captcha stammte, Verbindung aufnehmen, um
festzustellen, ob die Eingabe überhaupt richtig war. Hier gehen also mehrere
Male Datenströme hin und her.
Gerade diese Spamfallen beweisen, daß komplizierter nicht automatisch sicherer ist. Ganz im Gegenteil, je komplizierter ein Mechanismus ist, umso leichter läßt er sich im Regelfalle manipulieren. Dagegen können Sie diese Methoden ohne Probleme selbst einbauen, und die gesamte Auswertung findet auf Ihrem Server statt. So müssen Sie keinerlei Informationen an Dritte weitergeben, so daß sämtliche anfallende Informationen ausschließlich bei Ihnen verbleiben. Dadurch lassen sich diese Sicherheitsvorkehrungen nicht von außen angreifen.
nach obenBonus: Captcha mit inverser Logik
Sie haben richtig gelesen: Wenn man es richtig aufzieht, kann man Captchas sehr
wohl dazu verwenden, um Bots draußen zu halten, ohne dabei Ihren Nutzern auf
den Zeiger zu gehen.
Wenn Sie sich jetzt sagen „Der tickt doch nicht ganz
richtig! Erst sagt er, Captchas solle man vermeiden, aber hier will er uns
jetzt weismachen, daß es doch geht?“, so kann ich Sie beruhigen:
Captchas sind nach wie vor nicht notwendig, um
wirkungsvolle Spamfallen aufzubauen, aber mit einem kleinen Trick kann man
einen Spambot so gründlich in die Irre führen, daß der Programmierer nicht mehr
weiß, was überhaupt los ist.
Sie binden hierzu einfach ein Captcha (im Eigenbau oder aus einer anderen
Quelle) ein, das sich mit etwas Aufwand per OCR-Software knacken läßt, legen
ggf. die notwendigen Eingabefelder an (immerhin soll es ja aussehen wie die
Abfrage für ein echtes Captcha), zeichnen sie passend aus, so daß, sollte
irgendwer das Ganze doch zu Gesicht bekommen, niemand auf die Falle
hereinfällt, und verstecken das Ganze wiederum mittels CSS, ganz wie beim
Schwindel-Eingabefeld.
Ist das zugehörige Eingabefeld leer, so haben Sie es entweder nicht mit einem
Bot zu tun, oder er hat es aus irgendeinem Grund leer gelassen. Finden Sie hier
jedoch eine Eingabe, so behandeln Sie es einfach wie das oben beschriebene
Schwindel-Eingabefeld und weisen die übermittelte Nachricht ab. Und wenn man
besonders gut drauf ist, so strafe man den Bot einfach bei erfolgreich gelöstem
Captcha ab, indem man ihm eine besonders lange Sperrfrist verpaßt. Zudem greife
man dann auch noch zum
Gaslighting
und behaupte, daß das Captcha falsch gelöst worden wäre, obwohl das, was
übergeben worden ist, stimmt, um zusätzliche Verwirrung zu stiften.