
So weit, so gut. Probieren wir das Ganze doch mal. Oh, nach Ausfüllen des Formulars mit inkorrekter Kontrollnummer kommt ein JavaScript-Fenster mit einer Fehlermeldung. Moment mal:
JavaScript?!?! Um Bots von der Seite fernzuhalten? Und weshalb ändert sich das CAPTCHA nicht nach einem Reload? Das muß ich mir näher angucken.
Hm. Irgendwie hat da jemand gründlich mißverstanden, wie das Ganze funktioniert:
1. CAPTCHAs sind dynamisch und nicht SRC=“../../GRAFIK/Code.gif”
2. Den Wert eines CAPTCHAs zu überprüfen, indem man ihn auf dieselbe Seite packt wie das CAPTCHA, ist wenig schlau:
if(document.Formular.Code.value != “4711”)
{
alert(“Bitte geben Sie hier die Kontrollnummer ein!”);
document.Formular.Code.focus();
return false;
}
Aber das ist alles völlig egal, denn
3. Warum sollte ein Spambot JavaScript aktiviert haben?
Da ist es wieder, eines der Kernprobleme der Webdesigner. Nur, weil eine hohe Wahrscheinlichkeit besteht, daß Clients eine Unterstützung für Feature X mitbringen, bedeutet das noch lange nicht, daß jeder Client das tut. Oft agieren nämlich gerade diejenigen, für die man beispielsweise eine Formularvalidierung installiert, an einem der Ränder des typischen Featuresets: Spambots sind normalerweise sehr spezialisiert, implementieren mit Ach und Krach GET und POST und interessieren sich generell für wenig mehr als eine URL-Liste und die einzutütenden Inhalte.
Auch ein Accessibility-optimierter Browser wird vermutlich mit einem Javascript-Popup wenig anfangen können, und schwer körperbehinderte Menschen freuen sich bestimmt ganz doll, wenn sie ihren Cursor mit viel Mühe in die Bildschirmmitte bewegen müssen, um auf “OK” zu klicken.
Halten wir mal fest:
Clientbasierte Formularvalidierung ist Unsinn!
Das scheint sich noch nicht so herumgesprochen zu haben, wie man das gerne möchte - und Negativbeispiele wie das o.g. gibt es zuhauf. Aber NIEMAND, und ich meine das genauso, wie ich es schreibe, NIEMAND sollte je auf die absurde Idee kommen, eine Formularvalidierung per JavaScript sei völlig ausreichend für ein beliebiges Formular.
So wie HTML::QuickForm das macht, nämlich optional als zusätzliche Warnung für den Client, kann das sinnvoll sein (wenn unter Accessibility-Gesichtspunkten auch eher zweifelhaft), aber als ausschließliches Merkmal - never ever.
Weiter halten wir fest:
statische CAPTCHAs sind keine CAPTCHAs!
Es ist nicht ausreichend, einfach irgendeine Zahl, ein Wort oder sonstwas in sein Formular zu schreiben, und auf eine wundersame Heilung von der Spamkrankheit zu hoffen. So funktionieren Spammer nämlich nicht, und den Gedanken eines CAPTCHAs erfüllt ein solcher Mechanismus ebenfalls nicht. OCR-Mechanismen, um eine in großer Schrift schwarz auf weiß geschriebene 1234 zu erkennen, sind weitgehend trivial.
UPDATE: Danke an Jörg Behrens für den Tip mit gocr, das kann sowas nämlich gut:
absynth:~# gocr -i Code.gif
4711
So einfach ist das.
Daher sollte ein CAPTCHA immer mindestens 3 Farben, schräggestellte und verzerrte Zeichen und möglichst ein dynamisches Hintergrundmuster enthalten. Mit der Accessibility ist es dann allerdings vollständig Essig, denn ein stark sehbehinderter Websurfer, der auf ein CAPTCHA stößt, kann sich dieses nicht vorlesen lassen und wird den zu tippenden Satz nicht mit eigenen Augen erkennen können. Bei manchen CAPTCHAs schaffen das ja Normalsichtige nicht einmal in jedem Fall.
Es existieren inzwischen konkrete Projekte, die sogenannte CAPTCHAs (denn jedes maschinenlesbare CAPTCHA ist keines) algorithmisch erkennen lernen, und die Quote der Erkennung ist gar nicht mal übel. Das Projekt
Breaking a Visual CAPTCHA an der Uni Berkeley ist nur ein Ansatz, um diese en vogue geratene Variante der Spamvermeidung zu überlisten.
Für PHP-Entwickler gibt es die Klasse
Pear::Captcha, die allerdings beim letzten Versuch, den ich unternahm, völlig unbenutzbar war. CAPTCHAs selber zu basteln, ist ein relativ einfacher Prozeß, der auf drei Schritte hinausläuft:
1. Phrase generieren (entweder ein Wort oder randomized, allerdings Lesbarkeitsregeln gehorchend), Phrase in Sessionvariable speichern
2. Bild generieren (möglichst viel Störung, aber für Menschen einwandfrei lesbar)
3. Phrase in Session mit Phrase aus Formulareingabe abgleichen - fertig.
Mal sehen, ob ich in nächster Zeit die Motivation finde, sowas mal in schön hinzuhacken...