SPAM protection methods N° 2: timing everything
"SPAM protection methods" series part 2, ominous title "Timing is everything". idea: users web form fill vaj seconds Dung whole form fill pagh. omniscient Wikipedia: office management clerk keystrokes ~230 characters per minute. jIH self-test 512 per minute (naDev find laH). average value assume: 400 characters per minute law' nom type laH vaj bot most likely (form automatically fill). Let's go.
1. mathematics (yuck)
400 characters per minute vaj keystrokes per second chay' law': 400 / 60 = 6.66666667 (7). 7 keystrokes per second law' - critical. average (sometimes faster, slower) 5 seconds Dung 35 (= 5x7) keystrokes law' vaj bot laH. math done. easy.
2. process
interval set: 5 seconds Hoch keystroke counter reset. "keypress" Hoch counter +1, 35 exceed vaj bot against measures. "measures": POST request captcha.php Daq send (captcha contain) 'ej session Daq bot store. simple: jQuery lo'.
3. Le Javascript
var typecounter = 0;
setInterval(function(){
typecounter = 0;
}, 5000);
$(document).keypress(function(){
typecounter++;
if (typecounter > 35){
$.post("captcha.php", { action: 'block' }).done(function(data) {
if (data == 'block') {
location.reload();
}
});
}
});
5 seconds Hoch typecounter 0 reset. keypress +1, 35 reach vaj page reload 'ej error message show.
4. Le PHP (captcha.php)
session_start();
$_SESSION['is_bot'] = true;
die('block');
captcha.php: session variable 'is_bot' true set 'ej message 'block' return.
5. Stay out!
bot site Daq come pagh (error message immediately), file protect Hoch beginning Daq two lines add:
session_start();
if (isset($_SESSION['is_bot']) && $_SESSION['is_bot'] === true) die("Kein Zugang für Bots");
session start 'ej session variable 'is_bot' value check (captcha.php Daq set). 'true' vaj output end, message 'Kein Zugang für Bots' show.
6. Optimizations
optimal: captcha first ask. human quickly type'a'? Let's go.
7. Captcha
file Daq two small division layers (DIVs) add, fancy text. styles externalize pagh header Daq put pagh (overview).
<div id="captcha_wrapper" style="display:none; width:100vw; height:100vh; background-color:rgba(0,0,0,.8); align-items: center; justify-content: center;">
<div style="background-color:#fff; padding:1em;">
<h2>Bist du ein Mensch</h2>
Hoooman! Du tippst ja schnell - leider lässt das für mich nur den Schluss zu, dass du ein böser Bot bist. Daher bitte ich dich, folgendes einfaches Captcha zu lösen. Was siehst du für einen Text in dem Bild?
<img src='captcha.php' id='captcha_out'>
<input type="text" id="txtCaptcha">
<button id="checkCaptcha">Prüfen</button>
</div>
</div>
input '#txtCaptcha' Daq image captcha enter, button '#checkCaptcha' entered value check.
8. Le Javascript - captcha vaD
JavaScript modify. "location.reload" pagh captcha DIV show.
var typecounter = 0;
setInterval(function(){
typecounter = 0;
}, 5000);
$(document).keypress(function(){
typecounter++;
if (typecounter > 35){
$.post("captcha.php", { action: 'block' }).done(function(data) {
if (data == 'block') {
$("#captcha_wrapper").css('display', 'flex');
}
});
}
});
above rap, line
$("#captcha_wrapper").css('display', 'flex');
new. 'display: flex' choose (captcha box center).
9. Captcha.php
PHP code adapt. user block (temporary), captcha return 'ej next step Daq compare.
session_start();
if (isset($_POST['action']) && $_POST['action'] == 'block'){
$_SESSION['blocked'] = true;
die('block');
}else if (isset($_POST['action']) && $_POST['action'] == 'check'){
if ($_POST['value'] == $_SESSION['captcha']){
$_SESSION['human'] = true;
$_SESSION['is_bot'] = false;
die('unblock');
}
}else{
header('Content-Type: image/png');
$width = 200;
$height = 30;
$im = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($im, 255, 255, 255);
imagefilledrectangle($im, 0, 0, 399, 29, $white);
$characters = '123456789abcdefghijklmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ';
$randomString = '';
for ($i = 0; $i < 6; $i++) {
$char = $characters[rand(0, strlen($characters) - 1)];
imagestring($im, '2', 5+$i*20+rand(0, 10), 10, $char, imagecolorallocate($im, rand(0,100), rand(0, 100), rand(0, 100)));
$randomString .= $char;
}
$_SESSION['captcha'] = $randomString;
imagepng($im);
imagedestroy($im);
}
code experiment laH. 6 letters range [0-9a-Z] (letters o, O, 0 pagh - older users confusion avoid) :-)
10. captcha check
captcha value check. JavaScript add:
$("#checkCaptcha").click(function(){
$.post("captcha.php", { action: 'check', value: $('#txtCaptcha').val() }).done(function(data) {
if (data == 'unblock') {
$("#captcha_wrapper").css("display", 'none');
}else{
$("#captcha_out").attr("src", "captcha.php");
}
});
});
#checkCaptcha button click: action 'check' 'ej #txtCaptcha string post. 'unblock' vaj captcha wrapper hide, user normally continue. pagh vaj new captcha show.
11. value check
protected file Hoch beginning check change: $_SESSION['human'] true pagh check. already entered captcha vaj future "too fast typers" bot activity consider pagh.
session_start();
session_destroy();
$_SESSION['is_bot'] = false;
if (isset($_SESSION['is_bot']) && $_SESSION['is_bot'] === true && !$_SESSION['human'] === true) die("Kein Zugang für Bots");
"Kein Zugang für Bots" message funnier laH. really safe vaj captcha again ask - user captcha first correctly enter pagh (try pagh), browser close, new attempt start - theoretically session expire wait poQ (cookies delete).
TL;DR
- user 35 characters 5 seconds law' fast type? bot?
- captcha rap DIV show - user temporarily session via lock
- captcha ask - correct vaj session variable set; pagh - new captcha generate.