Man möchte manchmal Teile seiner Seite mittels Captchas schützen. Es gibt zahlreiche fertige Varianten, auch für wordpress. Diese haben fast immer den Nachteil, dass sie JavaScript, Flash, oder Sessions benutzen. Persönlich habe ich eine Abneigung gegen JavaScript und Flash. Sessions lassen sich nicht immer nachträglich nutzen und man erzeugt serverseitig etwas Last. Fakt ist, dass ich keine Sessions mag! Das schlimmste an fertigen Captcha-Lösungen ist der zum Teil invalide html-Code. Ich möchte validen xhtml 1.0 strict-Code haben und das Captcha sollte in mein Design passen. Wenn man die ganzen Anforderungen erfüllt haben möchte, so muss man wohl oder übel sein Captcha selbst programmieren.
Wie komme ich zum sicheren Captcha
Wenn ich auf Sessions verzichten möchte, so muss ich die Lösung des Captcha mit auf die Seite schreiben. Das kann man in einen nicht sichtbaren Feld machen. Damit man dieses Feld nicht so einfach auslesen kann, schreibt man einen Hash hinein bzw. man verschlüsselt den Inhalt.
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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | define(KEY, "Ich bin ein Key"); define(IV, "KlyV6gxG3MOPzlfuj8azF6sKKTnsdsiN58i0zjHA0EU="); function Crypt($plaintext){ $td = mcrypt_module_open('rijndael-256', '', 'ofb', ''); $iv = base64_decode(IV); $ks = mcrypt_enc_get_key_size($td); /* Create key */ $key = substr(md5(KEY), 0, $ks); /* Intialize encryption */ mcrypt_generic_init($td, $key, $iv); /* Encrypt data */ $encrypted = mcrypt_generic($td, $plaintext); /* Terminate decryption handle and close module */ mcrypt_generic_deinit($td); mcrypt_module_close($td); return base64_encode($encrypted); } function Decrypt($chiffre){ $td = mcrypt_module_open('rijndael-256', '', 'ofb', ''); $iv = base64_decode(IV); $ks = mcrypt_enc_get_key_size($td); /* Create key */ $key = substr(md5(KEY), 0, $ks); $chiffre = base64_decode($chiffre); mcrypt_generic_init($td, $key, $iv); $plaintext = mdecrypt_generic($td, $chiffre); mcrypt_generic_deinit($td); mcrypt_module_close($td); return $plaintext; } function draw_captcha_form(){ ..... $time = time() + 60*30; $captchaSolution = "Test" echo "\t\n\tBitte Captcha lösen<br/>\n"; // erzeuge ein Captcha echo "\t\n"; echo "\t" . ' <input name="captvalue" id="captvalue" value="" size="40" tabindex="4" type="text"/>' . "\n"; echo "\t" . ' <input name="captcha" value="'. Crypt($time . "~" . $captchaSolution . "~" . $REMOTE_ADDR) . '" type="hidden"/>' . "\n"; } function check_post($) { .... $captcha = $_POST['captvalue']; list($timeOld, $secret, $addr) = explode('~',Decrypt($_POST['captcha'])); .... if($timeOld <= time()){ echo "Deine Zeit ist abgelaufen"; return; } if($addr != $REMOTE_ADDR){ echo "Falsche IP"; return; } if($secret != $captcha){ echo "Falsches Captcha"; return; } ..... } |
Mit diesen Ideen kann man sich nun sein eigenes Captcha zusammen bauen. Ich generiere z.B. Matheaufgaben.
Du hast noch einen weiteren Vorteil von selbst gebauten Captchas vergessen: Sie blocken Bots wirklich!
Die Lösungen von der Stange sind doch längst in jedem beliebigen Robot gebrochen, doch es wird sich kein Angreifer extra Attacken gegen kleine Seiten wie unsere einfallen lassen. Daher denk ich, dass deine erste Variante (siehe http://0rpheus.net/tools/captcha) mit Sicherheit ausgereicht hätte um automatisierten Kommentar-Spam zu unterbinden.
Ich werde mir vorerst keine weiteren Sicherungen meines Captchas überlegen, aber wenn sich doch jemand die Mühe macht und mein Captcha in seinen Robot aufnimmt komm ich sicher auf deine Lösung zurück