« »
Spamschutzmechanismen für die eigene Homepage
NEIN! ... Ich habe Email in meinem Spam!

Titelbild: Die SPAM-Flut

Vorwort

Im Netz findet man unglaubliche Zahlen sobald es um das Thema Spam-Aufkommen geht. Einige sprechen da von ca. 80 Billionen Spam-Emails – jährlich. Tendenz: Steigend. Und diese Zahlen beziehen sich lediglich auf Email-Spam. Das Spam-Aufkommen auf der eigenen Website ist ebenfalls eine Plage für all jene, die an sich selbst den Anspruch stellen ihren Online-Auftritt Spam-frei zu halten.

In diesem Artikel erfahren Sie:

Was Sie vorher besitzen sollten:

Einleitung

Website-Spam: Er ist nicht ungefährlich, denn er enthält oft Links zu böswilligen „Angeboten“. Auch wirft er kein gutes Licht auf die eigene Website. Ja oft ist er sogar ein Merkmal ungepflegter oder verwaister Projekte. Schön anzusehen ist er auch nicht. Leider kann man ihn nicht einfach irgendwo abstellen: Er muss bekämpft werden. Da man als gewöhnlicher Web-Entwickler weder Zeit noch Lust hat den Ursprung dieses Übels zu bekämpfen, muss man notgedrungen Spam-Schutzmechanismen implementieren um diesem Problem habhaft zu werden.
Machen wir uns nichts vor: Wir können der Spam-Flut weder entkommen noch eine Sandburg bauen die stark genug wäre ihr für immer stand zu halten. Jedoch gibt es Mittel und Wege Spam zu „behindern“.
Da die wenigsten diese eigentlich stupide Aufgabe einem Menschen auftragen würden (welcher zudem unglücklicherweise auf Bezahlung besteht), muss der pfiffige Web-Entwickler diesen Vorgang automatisieren. Folglich ist es ein Kampf der Maschinen untereinander: Ein Turing-Test1. Doch wie unterscheidet eine Maschine einen Menschen von einem Artgenossen?

Allgemeine Vorgehensweise

Im Folgenden werden einige simple Methoden beschrieben, mittels PHP zu bestimmen, ob es sich bei einer Nachricht (z.B. in einem Gästebuch) um Spam handelt oder nicht. Normalerweise sollten mehrere dieser Methoden nebeneinander eingesetzt werden. Idealerweise baut man diese Mechanismen so, dass für einen Aspekt, der auf Spam hindeutet ein oder ggf. auch mehrere Punkte vergeben werden. Nachdem alle Funktionen die Nachricht analysiert haben, wird diese je nach Punktzahl entweder als Spam eingeordnet oder nicht. Das hat den Vorteil, dass man die „Strenge“, nach der Spam identifiziert wird leicht justieren kann. Um ganz sicher zu gehen, dass man niemanden zu unrecht als Spam abtut, kann man vermeintliche Spam-Nachrichten auch in der Datenbank belassen und nur vorerst sperren. Später geht man diese Nachrichten dann von Hand durch und gibt diese ggf. frei (siehe Abb. 2).

1. Schutz durch eine Blacklist

Eine naheliegende Lösung ist die sog. Blacklist, also die „schwarze Liste“. Auf ihr werden Schimpfwörter oder gar ganze Website-Adressen gepflegt. Enthält ein Eintrag (zum Beispiel in ein Gästebuch) eines oder mehrere dieser Wörter, kann davon ausgegangen werden, dass es sich dabei um Spam handelt. Oftmals wird von einer Blacklist mit der Begründung sie sei zu aufwändig und nicht ausreichend abgesehen. Dabei kann man bereits mit einer Handvoll Begriffen gut 60% allen Spams aussortieren. Man braucht sich dazu lediglich ein paar Spam-Einträge anzusehen. In den meisten Fällen geht es um Viagra oder andere medizinische Produkte. An zweiter Stelle folgen dann häufig „Werbe-Anzeigen“ für Websites mit pornographischem Inhalt. Bringt man nun nur ein paar gängige Begriffe aus diesen Bereichen der Blacklist bei, schiebt man damit einem Großteil des Spams einen Riegel vor. Ebenfalls nützlich sind Begriffe wie „kaufen“, „günstig“ oder „free“. Lediglich eine Sache sollte man dann noch beachten: Spam ist in den meisten Fällen englisch. Eine mehrsprachige Blacklist ist also ratsam.

Glücklicherweise ist die Umsetzung einer solchen Blacklist mittels PHP nicht sonderlich schwer:
Als erstes muss man natürlich ein Formular in HTML erstellt haben. Die Daten daraus müssen von einem entsprechenden PHP-Script abgefangen werden. Dann werden die einzelnen Begriffe der Blacklist zur einfacheren Handhabung in einen Array abgespeichert. Dazu gibt es zwei Möglichkeiten: Entweder werden die Begriffe und der Array direkt im Quellcode abgelegt, das kann allerdings bei einer langen Blacklist umständlich werden. Oder die Begriffe werden in einer anderen Datei (zum Beispiel einer TXT-Datei) abgelegt. Wobei die Begriffe jeweils durch einen Zeilenumbruch getrennt sein müssten. Handlicher ist letztere Methode. Ein Beispiel für eine sehr kurze Blacklist:

günstig
cheap
free
viagra

Durch folgenden Befehl wird die Datei (in diesem Fall „blacklist.txt“) aufgerufen und der Inhalt in einen Array ($blacklist_array) gespeichert:

1
$blacklist_array = file( 'blacklist.txt' );

Um herauszufinden, wie oft eine Zeichenkette in einer anderen Zeichenkette vorkommt, benötigt man den Befehl substr_count(). Dieser wird für jedes Element des Arrays, sprich für jedes „verbannte“ Wort neu ausgeführt. Jedes Vorkommen eines solchen Wortes wird ein Zähler um eins erhöht.

Sind diese beiden Grundlagen bekannt, wird der Rest nicht schwer:

Listing 1.1. Simple Blacklist-Funktion

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
// Inhalt der Nachricht abrufen
$nachricht = $_POST['nachricht'];

// blacklist.txt öffnen und in Array $blacklist_array speichern (Eine Zeile = Ein
// Element)
$blacklist_array = file( 'blacklist.txt' );

// Zähler für die gefundenen Wörter aus der Blacklist
$anzahl = 0;

// Jeweils ein Wort der Blacklist nehmen, in $blackword speichern und mitzählen,
// wie oft das Wort in der Nachricht auftaucht
foreach ( $blacklist_array as $blackword ) {
     $anzahl += substr_count( strtolower( $nachricht ), strtolower( trim( $blackword ) ) );
}

// Bestimmen, ob die Anzahl der "Spam-Wörter" niedrig genug ist
if( $anzahl < 2 ) {
     echo 'Nachricht wurde nicht als Spam eingestuft!';
} else {
     echo 'Nachricht wurde als Spam eingestuft!';
}
?>

Natürlich lässt sich dieses Script noch verbessern. So ist es momentan noch machtlos gegen Dinge wie „Leet-Speak2“ (Buchstaben durch ähnlich aussehende Zahlen ersetzen) oder sonstige Abstraktionen.

2. Schnell-Tippen: Zeit ist Geld?

Eine andere Möglichkeit Spam zu erkennen besteht darin die Schreibgeschwindigkeit zu ermitteln. Denn welcher Spam-Bot nutzt denn nicht „Copy-&-Paste“? Ein Spam-Eintrag benötigt meist nur sehr kurze Zeit. Misst man nun die Zeit seit dem Laden der Formular-Seite bis zum Empfang der Formular-Daten, kann man daraus und aus der Anzahl aller Zeichen im Formular die Tastenanschläge errechnen. Das Ergebnis ist zwar leicht verfälscht, wenn ein echter Benutzer die Seite besucht, da dieser nicht sofort anfängt zu tippen, doch das setzt seine errechneten Tastaturanschläge ja nur herunter.

Die Zeit berechnen wir mit einem Timestamp (also sekundengenau). Es liegt zwar nahe, diesen Timestamp zusammen mit den anderen Formular-Daten in einem versteckten Feld zu verschicken, dies ist aber zu unsicher, da der Spam-Bot diese Werte manipulieren kann. Aus diesem Grund hinterlegen wir den Timestamp in einer Session. Bei der Auswertung rufen wir ihn dann wieder ab, errechnen die Differenz, ermitteln die Anzahl aller Zeichen im Formular und errechnen daraus die Tastenanschläge. Ein verdächtiger Wert liegt bei ungefähr 8 Anschläge pro Sekunde aufwärts.

Auf der Seite des Formulars:

Listing 2.1. Speichern des Timestamps in die Session-Variable

1
2
3
4
5
6
<?php
     // Session-Start
     session_start();
     // Speichern des Timestamps in die Session-Variable
     $_SESSION['spam_check_start'] = time();
?>

Bei der Auswertung:

Listing 2.2. Auswertung der Daten und Errechnen des Tastenanschlags

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
     // Session-Start
     session_start();
?>
<em>[… HTML-Grundgerüst, etc. ...]</em>
<?php
     // Name abrufen
     $name = $_POST['name'];

     // Inhalt der Nachricht abrufen
     $nachricht = $_POST['nachricht'];

     // Timestamp abrufen
     $spam_check_start = $_SESSION['spam_check_start'];

     // Aktuellen Timestamp ermitteln
     $spam_check_ende = time();

     // Differenz ermitteln
     $spam_check_dauer = $spam_check_ende - $spam_check_start;

     // Anzahl aller Buchstaben errrechnen
     $anzahl_aller_buchstaben = strlen( $name.$nachricht );

     // Anschlage pro Sekunde errrechnen
     $anschlaege_pro_sekunde = ( $anzahl_aller_buchstaben / $spam_check_dauer );

     if ( $anschlaege_pro_sekunde < 9 ) {
          // ggf. Meldung ausgeben
          echo 'Nachricht wurde nicht als Spam eingestuft!';
     } else {
          // Fehlermeldung ausgeben, ggf. Punkt-Zähler entsprechend verändern
          echo 'Nachricht wurde als Spam eingestuft!';
     }
?>

3. Leere Eingabe-Felder

Da Spam-Bots oft die Angewohnheit haben alle Felder auszufüllen, kann es schnell passieren, dass auch unsichtbare Formular-Elemente mit Inhalten gefüllt werden. Dies tun normale Besucher nicht: Ein weiteres Unterscheidungsmerkmal.
Dazu muss im Formular lediglich ein unsichtbares, leeres Element hinzugefügt werden. Inzwischen haben Spam-Bots meistens schon gelernt, dass „versteckte Eingabefelder“ (<input type=“hidden“ />) besser ignoriert werden sollten. Deshalb ist es ratsamer ein ganz normales Eingabefeld (<input type=“text“ />) anzulegen, welches auch keinen auffälligen Namen trägt. Dieses wird dann einfach mit der CSS-Eigenschaft display unsichtbar gemacht (<input type=“text“ style=“display:none;“ />). Ist das Feld bei der Auswertung mit Inhalt gefüllt, steigt erneut die Spam-Wahrscheinlichkeit.

4. Kannst du rechnen?

Eine weitere beliebte Möglichkeit Spam abzufangen besteht darin, dem Besucher eine einfache Rechenaufgabe zu stellen. Das Ergebnis muss (korrekt) in ein Formularfeld eingetragen werden. Es wird bei der Auswertung überprüft. Da viele Spam-Bots immer noch nicht „rechnen“ können, ist es ein geeignetes Kriterium. Leider ist es jedoch für den Besucher mit Mehraufwand verbunden. Die Entscheidung, ob dies zumutbar ist, liegt beim Entwickler.

Auf der Formular-Seite müssen zuerst die beiden Zufalls-Zahlen und die Rechenart (Addition oder Subtraktion) ermittelt werden. Das Ergebnis wird in die Session-Variable gespeichert, die Rechnung im Formular ausgegeben.

Listing 4.1. Vorbereiten einer Rechenaufgabe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
     // Session-Start
     session_start();

     // Ermitteln der ersten Zufallszahl
     $zahl1 = rand ( 0, 20 );

     // Ermitteln der zweiten Zufallszahl
     $zahl2 = rand( 0, 20 );

     // Bestimmen einer Rechenart (+ o. -)
     // und dem entsprechenden Ergebnis
     if ( $zahl1 < $zahl2 ) {
          $rechenart = ' + ';
          $ergebnis = $zahl1 + $zahl2;
     } else {
          $rechenart = ' - ';
          $ergebnis = $zahl1 - $zahl2;
     }
     
     // Speichern des Timestamps in die Session-Variable
     $_SESSION['spam_check_rechnung'] = $ergebnis;
?>

Listing 4.2. Ausgeben der Rechenaufgabe im Formular

1
2
<label>Bitte ausrechnen: <?php echo $zahl1.$rechenart.$zahl2; ?></label><br />
<input type="text" name="spam_check_rechnung_besucher" /><br />

Die Auswertung ist nun ziemlich simpel. Auch hier könnten Spam-Punkte vergeben werden:

Listing 4.3. Auswertung der Rechnung

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
     // Session-Start
     session_start();
?>
<em>[... HTML-Grundgerüst, etc. ...]</em>
<?php
     // Korrektes Ergebnis abrufen
     $spam_check_rechnung = $_SESSION['spam_check_rechnung'];
           
     // Erhaltenes Ergebnis abrufen
     $spam_check_rechnung_besucher = $_POST['spam_check_rechnung_besucher'];

     // Auswertung
     if ( $spam_check_rechnung == $spam_check_rechnung_besucher ) {
          // ggf. Meldung ausgeben
          echo 'Nachricht wurde nicht als Spam eingestuft!';
     } else {
          // Fehlermeldung ausgeben, ggf. Punkt-Zähler entsprechend verändern
          echo 'Nachricht wurde als Spam eingestuft!';
     }
?>

Diese Methode funktioniert leider nicht mehr bei alle Spam-Bots, dennoch ist sie häufig noch effektiv, denn die Schwierigkeit für die Maschine besteht dabei nicht darin die Rechnung zu lösen, sondern zu begreifen, dass sie eine Rechnung lösen muss.

5. Wie heißt Max mit Vornamen?

Ähnlich der Rechenmethode (s.o.) funktioniert auch folgende (verbesserte) Methode sehr gut: Erneut muss der Besucher die richtige Eingabe machen um sich als Nicht-Spammer zu identifizieren. Nur handelt es sich nicht um eine Rechenaufgabe, sondern um eine Frage. Die Fragen sollten folgende Kriterien erfüllen:

Sie sollten…

… zahlreich sein.
… sich selbst beantworten.
… in einem Wort beantwortet werden können.
… nur eine mögliche Antwort zulassen.

Beispiele für solche Fragen:

Die Schwierigkeit für die Maschine besteht hier darin, dass sie semantisch erfassen muss. Das heißt: Sie muss erst einmal die Frage verstehen. Das ist aber gar nicht so einfach.

Wie funktioniert dies nun im Detail?
Zuerst brauchen wir eine Liste mit Fragen und Antworten. Dazu verwenden wir erneut einen Array. Die Daten werden diesmal nicht in eine TXT-Datei gelegt, sondern direkt in den Array. Diesen kann man ja bei Bedarf in eine andere PHP-Datei auslagern. Auf der Formular-Seite ermitteln wir dann per Zufall eine Frage und lassen sie ausgeben. Die Antwort speichern wir in die Session-Variable. Die Frage samt Eingabefeld wird im Formular ausgegeben:

Listing 5.1. Generierung und Ausgabe einer Frage.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
     // Session-Start
     session_start();

     // Erstellen des Arrays (<Nummer der Frage> => <Frage>, <Antwort>)
     
     $fragen_array=array(
          0 => array('Wie hei&szlig;t Max mit Vornamen?', 'Max'),
          1 => array('Welche Farbe hat ein rotes Auto?', 'rot'),
          2 => array('Wieviele Ecken hat ein Dreieck?', 'drei'),
          3 => array('Wie viele Seiten hat ein 200-seitiges Buch', '200'),
          4 => array('Fridas Mofa ist gelb. Welche Farbe hat es?', 'gelb'),
          );

     // Ermitteln der Frage
     $frage_nummer = rand( 0, count( $fragen_array ) - 1 );

     // Speichern des Timestamps in die Session-Variable
     $_SESSION['spam_check_frage'] = $fragen_array[$frage_nummer][1];
?>

[... HTML-Grundgerüst, etc. ...]

1
2
<label>Beantworte: <?php echo $fragen_array[$frage_nummer][0]; ?></label><br />
<input type="text" name="spam_check_frage_besucher" /><br />

Bei der Auswertung des Formulars wird es auf Spam überprüft, indem einfach die Antwort des Besuchers mit der richtigen Antwort aus der Session-Variable verglichen wird. Vor dem Vergleich jedoch werden beide Antworten mit der Funktion strtolower() in Kleinbuchstaben umgewandelt, damit Abweichungen in Groß- und Kleinschreibung irrelevant werden:

Listing 5.2. Auswertung der Antwort des Besuchers.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
     // Session-Start
     session_start();
?>
<em>[... HTML-Grundgerüst, etc. ...]</em>
<?php
     // Korrektes Ergebnis abrufen
     $spam_check_frage = $_SESSION['spam_check_frage'];
           
     // Erhaltenes Ergebnis abrufen
     $spam_check_frage_besucher = $_POST['spam_check_frage_besucher'];

     // Auswertung
     if ( strtolower( $spam_check_frage ) == strtolower( $spam_check_frage_besucher ) ) {
          // ggf. Meldung ausgeben
          echo 'Nachricht wurde nicht als Spam eingestuft!';
     } else {
          // Fehlermeldung ausgeben, ggf. Punkt-Zähler entsprechend verändern
          echo 'Nachricht wurde als Spam eingestuft!';
     }
?>

Natürlich lässt sich auch dieses Beispiel noch stark ausbauen. So ist ein größerer Fragen-Katalog ebenso von Vorteil, wie mehrere Antwortmöglichkeiten (um verschiedenen Schreibweisen, etc. vorzubeugen).

6. Wo hast du eigentlich deine Augen?

Eine Abwandlung der semantischen Frage (s.o.) ist sogar noch effektiver und sicherer als selbige: Anstatt eine Frage zu stellen, muss der Inhalt eines Bilds mit nur einem Wort beschrieben werden. Auf dem Bild sollten einfache Dinge mit kurzen Bezeichnungen abgebildet sein. Außerdem sollte nur genau ein Gegenstand zu sehen sein, damit keine Verwirrung aufkommt. So könnte der Besucher zum Beispiel gebeten werden eine Birne, einen Apfel, einen Hund, ein Haus oder Millionen andere Dinge zu identifizieren.
Die technische Umsetzung funktioniert vom Prinzip her genauso, wie die der semantischen Frage (s.o.). Nur wird hier keine Frage ausgegeben, sondern ein kleiner HTML-Code um das entsprechende Bild einzubinden.

7. Doppelt hält besser?

Da Spam-Bots oft die Angewohnheit haben Felder, von denen sie nicht wissen, was das Script an Inhalten erwartet, einfach mit irgendwelchen Links zu füllen, kommt es auch oft vor, dass solche Felder mit den gleichen Inhalten gefüllt werden. Es lohnt sich also, alle Eingabefelder auf doppelten Inhalt zu prüfen. Wurden mehrere Eingabefelder identisch ausgefüllt, handelt es sich wohl um einen Spam-Bot. Auch hierfür könnten bei Bedarf wieder Spam-Punkte vergeben werden.

8. Captcha im Eigenbau

Leider werden die Spam-Bots immer besser. Um dieser Entwicklung entgegen zu treten, muss man sich schon tolle Dinge einfallen lassen. Die oben beschriebenen Methoden sollten in Kombination in den meisten Fällen hinreichend sein. Um die Sicherheit noch weiter zu steigern, bieten sich sog. Captchas3 an. Das sind kleine Grafiken, welche eine Zeichenkombination abbilden, welche der Besucher abtippen muss. Das ist im Prinzip auch eine gute Idee. Leider hat sie bei den meisten Umsetzungen einige Nachteile:

Da Spam-Bots die Fähigkeit entwickeln die Codes solcher Grafiken auszulesen, werden dies immer abstrakter und unlesbarer.
Damit der Code nicht mit einem Wörterbuch abgeglichen werden kann, werden nur noch zufällig generierte Buchstaben- und Zahlenkombinationen verwendet.
Daher empfinden die Besucher empfinden sie schnell als lästig.

Diese Nachteile kann man aber auch recht einfach beseitigen oder zumindest abschwächen:

So sollte ein Bild nicht verunstaltet werden, nur damit man die Schrift nicht mehr lesen kann. Dann sollte man lieber eine ausgefallenere Schriftart nehmen. Bunte Sterne, Hintergründe und Linien sind ebenfalls hinderlich. Sie erhöhen zwar die Sicherheit, schrecken dafür aber Besucher ab, wenn sie nicht zum Design passen oder zu viel Zeit beanspruchen.
Zufällig generierte Codes müssen nicht wie Kauderwelsch klingen: Zahlen kann man eigentlich weglassen, denn ob 26 oder 36 Zeichen zur Auswahl stehen macht auch keinen besonders großen Unterschied mehr. Werden nur Buchstaben verwendet, kann man schön-klingende Phantasie-Wörter generieren indem man Konsonanten und Vokale abwechselt. Das vermindert die Sicherheit zwar ein wenig, aber auch das nur unter der Voraussetzung, dass der Spam-Bot auf so etwas programmiert wurde.
Wie oben bereits angesprochen können auch Bilder von Gegenständen, die es zu benennen gilt, als Captchas verwendet werden, denn solch eine Aufgabe setzt eine hohe Rechenleistung des Spam-Bots voraus. Vergessen wir nicht, dass das menschliche Gehirn ein Meister das abstrakten Denkens ist.
Auch könnte man die langweiligen Codes durch die oben beschriebenen Fragen ersetzen. Dann steht der Spam-Bot nämlich nicht nur vor dem Problem die Frage „Wie heißt Max mit Vornamen?“ zu beantworten, sondern diese auch erst mal zu lesen.

Nun wollen wir ein ganz simples Captcha basteln und es mit unseren Fragen (s.o.) kombinieren. Dazu verwenden wir die Bordmittel PHPs und ein angepasstes Formular. Die Grafiken werden „on-the-fly4“ generiert. Dazu benötigen wir ein zusätzliches PHP-Script, welches als Grafik (mit Image-Tag) in das HTML-Formular eingebunden wird und die richtige Lösung in die Session-Variable schreibt:

Listing 8.1. Generierung eines Captchas

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?php
     // Session-Start
     session_start();

     // Senden des Headers
     header( "Content-type: image/png" );
     
     // Erstellen des Arrays (<Nummer der Frage> => <Frage>, <Antwort>)
     $fragen_array = array(
          0 => array('Wie heißt Max mit Vornamen?', 'Max'),
          1 => array('Welche Farbe hat ein rotes Auto?', 'rot'),
          2 => array('Wieviele Ecken hat ein Dreieck?', 'drei'),
          3 => array('Wie viele Seiten hat ein 200-seitiges Buch', '200'),
          4 => array('Fridas Mofa ist gelb. Welche Farbe hat es?', 'gelb'),
          );

     // Ermitteln der Frage
     $frage_nummer = rand( 0, count( $fragen_array ) - 1 );

     // Abspeichern der Frage
     $frage = $fragen_array[$frage_nummer][0];

     // Speichern der Antwort in die Session-Variable
     $_SESSION['spam_check_frage'] = $fragen_array[$frage_nummer][1];

     // Generieren der Grafik (400x30)
     $grafik = imagecreate( 400, 30 );
     
     // Hintergrund der Grafik weiß machen
     imagecolorallocate( $grafik, 255, 255, 255 );

     // Text-Farbe generieren (Schwarz)
     $text_farbe = imagecolorallocate( $grafik, 0, 0, 0 );

     // Text ausgeben. Parameter:
     // Variable der Grafik
     // Schriftgröße
     // Abstand zum linken Rand
     // Abstand zum oberen Rand (Ausrichtung wird so berechnet, dass die Schrift
     // mittig steht)
     // Text
     // Farbe des Schriftzugs
     ImageString ($grafik, 4, 20, ceil( 15 - ( imagefontheight( 4 ) / 2 ) ), $frage,
          $text_farbe);
     
     // Grafik ausgeben (im PNG-Format)
     imagepng( $grafik );
?>

Das Formular ist im Prinzip das gleiche wie in Listing 5.1. Nur wird die Frage nicht dort, sondern in der Datei captcha.png.php generiert. Diese wiederum wird eingebunden:

1
2
3
4
<img src="captcha.png.php"
alt="Bitte aktivieren Sie die
Anzeige von Grafiken in Ihrem
Browser!" /><br />

Die Auswertung bleibt unverändert (siehe Listing 4.2).

Mithilfe solcher Captchas ist man nun einen ganzen Schritt weiter. Natürlich lässt sich diese Methode aber noch stark ausbauen.

Instant-Lösungen

Im Bereich Spam-Abwehr gibt es viele Angebote. Besonders wenn es um Captchas geht. Die interessantesten Lösungen sind folgende:

1. Die wohl bekannteste Lösung lautet reCaptcha (Website: www.google.com/recaptcha). Es handelt sich dabei um ein System, welches von Google übernommen und fortgeführt wurde. Google scannt alte Bücher und Zeitschriften ein. Die einzelnen Wörter landen in einer riesigen Datenbank. Wird ein reCaptcha aufgerufen, bekommt der Besucher zwei Wörter zu sehen und muss sie abtippen. Das Besondere: Die Antworten werden gespeichert. Die einzelnen Wörter werden mehrmals von verschiedenen Besuchern abgetippt. Die Antwort, die am häufigsten gegeben wird, akzeptiert Google dann als „richtig“. Auf diese Weise werden wahnsinnig viele Captchas generiert und alte Zeitschriften digitalisiert. Diese Methode gilt als sehr effektiv und sicher. Allerdings ist die Integration in die eigene Website nicht unbedingt für „blutige Anfänger“ geeignet. Erfahrenere Programmierer sollten damit aber keine Probleme haben. Außerdem besitzt das reCaptcha ein recht auffälliges und platz-einnehmendes Aussehen. Das kann man zwar anpassen, aber das wiederum ist mit nicht wenig Arbeit verbunden. Alles in Allem eine der besseren Lösungen.
2. Eine weitere sehr schöne Captcha-Lösung ist SecureImage von www.phpcaptcha.org. Die Grafiken sind simpler und die Integration in die eigene Website ein wenig einfacher als bei anderen „Instant“-Lösungen.
3. Einen sehr interessanten Ausblick bietet www.animierte-captcha.de. Vor den Captchas „tanzen“ Symbole und Grafiken herum, sodass der Schriftzug nie vollständig zu sehen ist: Eine zusätzliche Herausforderung für einen Spam-Bot.

Diese „Instant“-Lösungen sind meistens schneller eingebaut als die eigenen Methoden. Außerdem sind sie in der Regeln doch deutlich sicherer und durchdachter. Dafür lassen sie sich nicht so leicht anpassen oder in das Design eingliedern. Auch handelt es sich (wie bei den Beispiele auch) fast immer um Captchas. Betrachtet man die oben beschriebenen Methoden, muss man sich allerdings fragen, ob man seine Besucher wirklich mit so etwas belästigen muss.

Erweiterungen für Content-Management-Systeme

Besonders komfortabel lebt man, wenn man ein CMS5 für seine Website verwendet, denn für diese gibt es eigentlich immer Erweiterungen, Plugins oder Addons. Mit diesen lassen sich die Spammer schon deutlich einfacher ausschalten.

Eine kurze Übersicht hier:

WordPress:

Joomla

Contao (ehemals TypoLight):

Typo3:

Schutz einer Email-Adresse vor Crawlern

Da in dem Impressum jeder Website eine gültige Email-Adresse stehe muss, ist dies ein beliebter Angriffspunkt für Email-Crawler6. Diese lesen die Adresse aus und speichern sie in ihre Datenbank. Wie von Zauberhand landet dann Spam im Posteingang. Um dies zu verhindern gibt es wahnsinnig viele Methoden. Einige besser, andere schlechter:

Kodierung der einzelnen Zeichen: Jedes Zeichen wird in den entsprechenden HTML-Sonderzeichencode umgewandelt. Das ist die beliebteste Lösung. Leider auch die mit am wenigsten effektive, denn die Crawler sind schon lange in der Lage diesen Trick zu durchschauen.
Einbinden als Grafik: Effektiver, jedoch leider auch nicht besonders ansehnlich und total „Copy-&-Paste“-unfreundlich. Die Adresse wird als Grafik gespeichert und eingebunden. Nicht optimal.
Maskieren der Adresse: Das @ wird durch Zeichenfolgen wie „ät“, „at“, „[at]“, etc. ersetzt. Doch auch das können die Crawler mittlerweile ganz gut durchschauen.
Aus zwei mach’ eins: Dabei handelt es sich um einen kleinen HTML-Trick. Es werden zwei Email-Adressen hintereinander gesetzt. Jede für sich ist nicht existent (bzw. totaler Quatsch). Streicht man jedoch den letzten Teil der ersten Adresse und den ersten Teil der letzten Adresse, entsteht aus dem Rest eine dritte: Die richtige. Alles was man tun muss, ist also mittels CSS die Teile dazwischen auszublenden. Beispiel:

1
2
3
4
<p>heinz
<small style="display:none;">
@nichtvorhanden.de&nbsp;gibtesnicht
</small>@mueller.info</p>

In diesem Beispiel sind die Adressen heinz@nichtvorhanden.de und gibtesnicht@mueller.info falsch. Lediglich die Kombination von beiden ist richtig: heinz@mueller.info.

Anregungen

Der Kreativität sind fast keine Grenzen gesetzt, geht es um die Spam-Bekämpfung. Lediglich die technischen Mittel binden den Programmierer an einen Rahmen. Dennoch sind weder alle Möglichkeiten Mensch und Maschine zu unterscheiden hier erklärt worden, noch sind sie ausgeschöpft. Alle Mechanismen lassen sich verbessern. Alle sind absolut ungesichert gegen Attacken (XSS und Co.). Alle Methoden einzubauen ist momentan auch noch viel Arbeit. Eine Klasse dafür zu schreiben wäre also von Vorteil und würde auf längere Sicht viel Aufwand ersparen. Kurzum: Auf geht’s!

Nachwort

Den Spam werden wir wohl nie ganz besiegen, doch mit geschickten Überlegungen lässt sich viel erreichen. Ich hoffe, ich konnte mit diesem Artikel einen Einstieg in das Thema bieten und zum Weitermachen anregen. Denn ausgereift sind die Scripte noch lange nicht.

Im Internet
http://www.google.com/recaptcha/ – reCaptcha-Website
http://www.phpcaptcha.org/ – Website des SecureImage-Projekts
http://www.animierte-captcha.de/ – Website der animierten Captchas
http://www.drweb.de/magazin/sichere-formulare-teil-4-spam-bots-masregeln/ – Ein Artikel zum Thema vom Dr. Web-Magazin
http://de.wikipedia.org/wiki/CAPTCHA – Wikipedia-Artikel zum Thema Captcha
http://www.bizeps.or.at/news.php?nr=8627 – Sehr unterhaltsamer Beitrag zum Thema Captcha und Benutzerfreundlichkeit von Peter Purgathofer

  1. Was ist eigentlich der Turing-Test?
    Der Turing-Test wurde 1950 von Alan Turing entwickelt, um festzustellen, ob eine Maschine ein Denkvermögen haben kann, dass dem des Menschen ähnelt. Oft wird dieser Begriff auch mit dem Stichwort „Künstliche Intelligenz“ in einem Atemzug genannt.
  2. Was ist Leet-Speak?
    Leet-Speak leitet sich ab von dem englischen Begriff „elite“ (Elite) und „speak“ (Sprache). Es bezeichnet das Ersetzen von Buchstaben durch ähnlich aussehende Zahlen oder auch Sonderzeichen. So wird auch oft nur von „1337“ gesprochen, was „leet“ in „Leet-Speak“ bedeutet. Die 1 steht dabei für das L, die 3 für das große E und die 7 für das T. Ursprünglich wurde diese Substitutions-„Chiffre“ verwendet um heikle Emails vor dem automatisierten Abhören zu schützen. Heute findet es oft im Gamer-Bereich Anwendung.
  3. Was sind eigentlich Captchas?
    Der Begriff „Captcha“ kommt aus dem Englischen und ist ein Akronym für „Completely Automated Public Turing test to tell Computers and Humans Apart“ („Vollautomatischer öffentlicher Turing-Test zur Unterscheidung von Computern und Menschen“). Ein Captcha ist meist eine Grafik, die ein verzerrtes Wort oder einen Code abbildet, der vom Besucher abgetippt werden muss, um zu beweisen, dass er selbst kein Spam-Bot ist.
  4. Was bedeutet noch gleich „on-the-fly“?
    Der Begriff „on-the-fly“ heißt im Bezug auf durch PHP generierte Grafiken, dass diese bei einem Aufruf durch einen Benutzer jedes mal neu erstellt werden müssen. Das heißt, sie können immer wieder anders aussehen. „On-the-fly“ bezeichnet also sozusagen den Moment zwischen Verlassen des Servers und der Ankunft beim Browser (auch wenn dies nicht ganz richtig ist).
  5. Wofür steht nochmal „CMS“?
    Ein CMS ist ein Content-Management-System (Inhalt-Verwaltungs-System). Es wird auf dem Webserver installiert und verwaltet Inhalte, Design und Struktur der Website sehr komfortabel. Die großen verfügen über eine Benutzerverwaltung, hunderte Erweiterungen und viele zusätzliche Funktionen. Große Websites kommen um ein CMS kaum noch herum.
  6. Worin besteht eigentlich der Unterschied zwischen Spam-Bot und Email-Crawler?
    Ein Spam-Bot durchsucht Websites nach Formularen, füllt sie aus und versucht so Backlinks für eine Website zu generieren oder Schadsoftware zu verteilen. Ein Email-Crawler such im Internet nach Email-Adressen und sammelt sie um später Spam zu verschicken.
Processing your request, Please wait....

// Bewerten

VN:F [1.9.11_1134]
Rating: 0.0/5 (0 votes cast)

// Share

// Kommentare


Du kannst einen Kommentar schreiben, oder einen Trackback auf deiner Seite einrichten.

3 Reaktionen zu “Spamschutzmechanismen für die eigene Homepage”

/*
Custom avatar Renzio42 sagt:

Hey Compufreak ;)
Hier passiert ja nich mehr wirklich viel…
Du könntest mal bei denen Partnerseiten meinen Eintrag updaten! Hab mittlerweile ne .de-Domain und meine Homepage hat sich mal wieder grundlegend geändert. Das HTML-Tutorial hab ich auch vorerstmal gelöscht…
Ich spezialisiere mich aktuell eher auf Minecraft und Designtechnisches ^^

VA:F [1.9.11_1134]
Rating: 0.0/5 (0 votes cast)
Custom avatar compufreak sagt:

Da hast du leider recht. Tatsache ist, dass ich im Moment einfach zu wenig Zeit habe. Ich weiß auch noch nicht, wie ich hier weitermachen will.
Erstmal muss ich noch zwei Projekte durchhauen und dann die kleine Überraschung für Silvester vorbereiten. Dann ist da noch die Schule! Und ich bin nicht mal G8!

Jedenfalls kriegt die Site hier in den nächsten Tage oder nächste Woche mal ein Update. Dann fix ich auch deinen Eintrag.

LG,
Till

VN:F [1.9.11_1134]
Rating: 5.0/5 (1 vote cast)
Custom avatar renzio42 sagt:

Hey, falls du dich mal um meinen Eintrag kümmerst, hier das neue Banner (mit GOLD :D ):
http://theprogrammer971.de/images/Banner/your_cake.png

VA:F [1.9.11_1134]
Rating: 0.0/5 (0 votes cast)
*/

Schreibe mir und lass' mich deine Meinung wissen!


Custom avatar Custom avatar Custom avatar Custom avatar Custom avatar Custom avatar Custom avatar Custom avatar Custom avatar Custom avatar Custom avatar Custom avatar Custom avatar Custom avatar Custom avatar Custom avatar Custom avatar Custom avatar Custom avatar Custom avatar Custom avatar Custom avatar Custom avatar Custom avatar


Facebook Twitter RSS MyNameIsE YouTube