Captcha Alternative: effektiver JavaScript SpamFilter

 

Ich wollte einen Besucherz√§hler f√ľr mein CMS¬†schreiben¬†und hab dabei relativ schnell bemerkt, dass der Gro√üteil der Besucher keine wirklichen Besucher, sondern automatische Abfragen¬†von Servern, sind. Das selbe Problem hatte ich seit jeher mit Formularen, diese wurden regelrecht zugespamt.¬†

Wie kann man effektiv einen Bot von einem richtigen Besucher unterscheiden?

Captcha

Eine sehr g√§ngige Variante sind¬†Captcha, kleine Bilder bei denen Benutzer Zahlen oder Buchstabenkombinationen beantworten m√ľssen. Aufgrund der Komplexit√§t der Bilder sind diese des √∂fteren nicht so leicht zu beantworten. Teilweise gibt es auch Varianten in denen eine Rechnung oder einfache Frage steht, Benutzer k√∂nnen diese meist leichter beantworten¬†als ein¬†Bot.

Das System funktioniert bei Formularen auf Kosten der Benutzerfreundlichkeit, nicht aber bei einem Besucherzähler. Wenn ich bei einem Besucherzähler echte Benutzer erkennen will, kann ich dem Leser kein Captcha zumuten um gezählt zu werden.

Aus¬†Benutzersicht w√ľrde ich behaupten: Captcha nerven.

Was macht ein Browser, was ein Bot nicht kann?

Wie sieht das mit JavaScript aus: wieviel Javascript kann ein Bot?

Die Idee: Wenn Teile der Seite dynamisch mit Javascript generiert werden, beispielsweise der Aufruf des Besucherzählers, könnten die Bots doch außen vor gelassen werden, oder?

das wollte ich testen:

 

Der Versuchsaufbau

jQuery lädt mittels ajax (also erst nachdem die Seite geladen wurde) dynamisch den Besucherzähler nach:

Jeder moderne Browser kann das, und da Bots meist nur statischen Inhalt abrufen können, kommen wir mit diesem Ansatz schon sehr weit.

 

Folgendes jQuery Script soll den Besucherzähler aufrufen:

$( document ).ready(function() {
$.ajax({url:'counter.php'});
});

(hier nur in vereinfachter Form dargestellt: nat√ľrlich k√∂nnte counter.php direkt aufgerufen werden und den Besucher dann z√§hlen, mit etwas zus√§tzlichem Code kann das leicht verhindert werden. Au√üerdem verlieren wir einige Informationen √ľber den Benutzer, z.B. den HTTP-Referrer.¬†Auch hier ben√∂tigen wir noch zus√§tzlichen Code. Um das Beispiel einfach zu halten, lasse ich diesen zus√§tzlichen Code jetzt mal absichtlich weg.)

 

Ein Bot m√ľsste als jQuery interpretieren k√∂nnen um die Datei zu laden.

Ich hab den Code auf meinen Seiten getestet und konnte mit dieser Variante alle Bots richtig einordnen, mit Außname des Googlebot: dieser hat unser Skript dennoch interpretiert und taucht in dem generierten Logfile auf:

Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)

Mozilla/5.0 (compatible; Googlebot-Mobile/2.1; +http://www.google.com/bot.html)

Googlebot kann also ein wenig JavaScript und folgt¬†dem¬†AJAX-Aufruf welcher mittels $( document ).ready(function() ¬†beim laden der Seite aufgerufen wird. Auch wenn Googlebot das Skript richtig ausf√ľhrt, gibt es dennoch Aktionen, die einem wirklichen Benutzer vorbehalten sind:

kann ein Bot die Maus bewegen?

Ich w√ľrde mal behaupten, ein Bot hat gar keine Maus, diesen Nachteil k√∂nnen wir n√ľtzen.

Ein Benutzer streicht doch bestimmt kurz mit der Maus √ľber den Bildschirm, wenn die Seite geladen wurde. Ger√§te ohne Maus haben ein Touchdisplay, welches beim Laden unweigerlich ber√ľhrt wird.

Mit dem Evenhandler mousemove und touchmove liefert ein Besucherzähler wirklich gute Ergebnisse:

$( "body" ).one("mousemove touchmove",function()  {
$.ajax({url:'counter.php'});
});

auch Googlebot wird mit dieser Variante richtig erkannt. 

 

F√ľr

Formulare

haben wir noch mehr M√∂glichkeiten, da der Benutzer das Formular ja ausf√ľllen muss, hier kann beispielsweise das Event focus() verwendet werden.

 

Die Idee:

Ein Event bef√ľllt mittels jquery und einem¬†Ajax Request ein verstecktes Formularfeld, der Server muss nach dem Post-Event √ľberpr√ľfen ob das Formularfeld den richtigen Wert enth√§lt. Die Berechnung des Wertes muss nat√ľrlich beim¬†Ajax Request und dem¬†eigentlichen¬†speichern des Formulares,¬†das selbe Ergebnis liefern. F√ľr die Berechnung kann beispielsweise ein Hash einer Kombination aus Uhrzeit und Clientinformationen, wie der IP Adresse oder √§hnliches, gew√§hlt werden.

Diese Variante macht Captcha oder √§hnliche Ans√§tze v√∂llig √ľberfl√ľssig.

 

Das Prinzip hab ich¬†in dem Content Management System LiBe CMS¬†umgesetzt und erfolgreich getestet, sowohl f√ľr den Besucherz√§hler, als auch f√ľr Formulare; siehe:Besucherz√§hler

positive Bewertung({{pro_count}})
Beitrag bewerten:
{{percentage}} % positiv
negative Bewertung({{con_count}})

DANKE f√ľr deine Bewertung!

Fragen / Kommentare


(sortiert nach Bewertung / Datum) [alle Kommentare(neueste zuerst)]

✍anonym
14.07.2020 14:53
Sehr cooler Ansatz. ABER:
„Ein Benutzer streicht doch bestimmt kurz mit der Maus über den Bildschirm, wenn die Seite geladen wurde. Geräte ohne Maus haben ein Touchdisplay, welches beim Laden unweigerlich berührt wird.“
Diese Annahme ist falsch. User mit Sehbehinderung oder auch User mit Körperbehinderungen, z.B. mit Tremor der Hände, nutzen weder Maus noch Touchscreen. Sie nutzen Tastaturen oder Eingabegeräte, die Tastatureingaben simulieren.
Möglicherweise gibt es noch andere Nutzergruppen, auf die die Annahme nicht zutrifft.

✍anonym
13.10.2015 12:27
User: Michael 
Mensch, da √ľberlegt man die ganze Zeit und entschlie√üt sich, die Frage zu posten, weil man nicht weiter kommt... und 2 Minuten sp√§ter f√§llt einem die L√∂sung ein :-)

F√ľr alle, die dasselbe Problem haben: Ich lese einfach den Titel der Seite in der Hauptseite aus uns speichere ihn in eine Variable. Diese √ľbergebe ich dann an die analyse.php, indem ich diese folgenderma√üen einbinde:

 $.ajax({url:'analyse.php?titel='});

In der Analyse.php lese ich den Wert mit GET aus und kann diesen dann in die Datenbank schreiben. So funktioniert es!

✍anonym
13.10.2015 12:17
User: Michael 
Moin, moin! Ich habe mir selbst ein Skript gebastelt, um mir live anschauen zu können, wieviele User gerade auf meinen Seiten sind. Und aufgrund der vielen Bots wichen die Zahlen von den Live-Stats von zB Google Analytics sehr weit ab. Dank Deines Beitrags kann ich nun realistischere Zahlen ausgeben. Denn ich laden die analyse.php-Datei einfach per Javascript nach.

Das Problem was ich nun habe: Ich kann jetzt nicht mehr auslesen, welche Seite der Besucher gerade anschaut. Entweder ist die Angabe leer oder aber es wird der Name der analyse.php ausgegeben; ich schaffe es aber nicht, den Namen der Datei ausgeben zu lassen, die vom User aufgerufen wird und innerhalb der dann die analyse.php nachgeladen wird. Gibt es hierf√ľr eine L√∂sung?

Gr√ľ√üe!

✍anonym
07.07.2015 17:19
User: udo 
geniale Sache!

Durch die weitere Nutzung der Seite stimmst du der Verwendung von Cookies zu Mehr Details