<?php
const KEY = 'Some random string';
const NUM_FIGURES = 3;
const TIMEOUT = 300;
const COOKIE_NAME = 'figaptcha';
class Figaptcha
{
protected $_key, $_timeout;
function __construct($key, $timeout)
{
$this->_key = $key;
$this->_timeout = $timeout;
}
function build($token, $data)
{
$expire = strval(time() + $this->_timeout);
$x = serialize($data) . '|' . $expire;
return strval($token) . '|' . $expire . '|' . hash_hmac('md5', $x, $this->_key);
}
function check($token, $data, $figaptcha)
{
if (!is_string($figaptcha)
|| !preg_match('%^([^|]+)\|([0-9]+)\|([0-9a-f]+)$%', $figaptcha, $matches)
|| $matches[1] != strval($token)
|| intval($matches[2]) < time()
) return FALSE;
$x = serialize($data) . '|' . $matches[2];
return hash_hmac('md5', $x, $this->_key) == $matches[3];
}
}
$selfRef = $_SERVER['PHP_SELF'];
$figaptcha = new Figaptcha(KEY, TIMEOUT);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (!isset($_COOKIE[COOKIE_NAME])
|| !isset($_POST['token'])
|| !isset($_POST['capcase'])
|| !$figaptcha->check($_POST['token'], array_keys($_POST['capcase']), $_COOKIE[COOKIE_NAME])) {
$message = 'U\'R FCKIN\' BOT!!!';
} else {
die('All right! <a href="'.$selfRef.'">Try again</a>');
}
}
$items = array();
for ($i = 0; $i < NUM_FIGURES; ++$i) {
$items[] = array(mt_rand(0, 3), mt_rand(0, 3));
}
$some = $items[mt_rand(0, NUM_FIGURES - 1)];
$rightAnswer = array();
foreach ($items as $i => $item) {
if ($item == $some)
$rightAnswer[] = $i;
}
$colours = array('red', 'blue', 'yellow', 'grey');
$figures = array('circle', 'triangle', 'square', 'cross');
$hint = $colours[$some[0]] . ' ' . $figures[$some[1]];
$token = mt_rand(1, 1000000);
$cookieValue = $figaptcha->build($token, $rightAnswer);
setcookie(COOKIE_NAME, $cookieValue, 0, '/', '', FALSE, TRUE);
?>
<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">
#message {width: 300px; padding: .5em; border: 2px solid red;}
#figaptcha {position: relative; overflow: hidden;}
#figaptcha .item {float: left; text-align: center;}
#figaptcha .answer {display: block; width: 100px; height: 100px; background: url('figures2.png');}
</style>
</head>
<body>
<?php if (isset($message)): ?><p id="message"><?php echo $message ?></p><?php endif; ?>
<form action="<?php echo $selfRef ?>" method="post">
<input type="hidden" name="token" value="<?php echo $token ?>" />
<p>Check ALL figures wich are <strong><?php echo $hint ?></strong></p>
<div id="figaptcha">
<?php
foreach ($items as $i => $item) {
list($colour, $figure) = $item;
$x = (-$colour * 100) + (400 * mt_rand(-10, 10));
$y = (-$figure * 100) + (400 * mt_rand(-10, 10));
?>
<label class="item"><input name="capcase[<?php echo $i ?>]" type="checkbox"/><br /><span class="answer" style="background-position: <?php echo $x ?>px <?php echo $y ?>px"></span></label>
<?php
}
?>
</div>
<input type="submit" name="submit" value="Post" />
</form>
</body>
Форум → Программирование → Пыхнуть хотите? → Готовые решения → Figaptcha
Figaptcha
Страницы: ← Следующая страница →
-
Выношу на ваш суд каптчу "узнай картинку". Использует куку в формате HMAC и скрытое поле со случайным токеном. Сессия не требуется.ιιlllιlllι унц-унц
-
Май 6, 2012, 1:51 п.п., спустя 40 минут 44 секунды
Без труда и без изменения класса переделывается в каптчу "секретные вопросы":ιιlllιlllι унц-унц -
-
Май 6, 2012, 2:46 п.п., спустя 31 минуту 22 секунды
грубая лесть! некруто, просто нормально. и пока она не распостраненная, боты под нее не заточятся )))ιιlllιlllι унц-унц -
Май 6, 2012, 4:12 п.п., спустя 1 час 26 минут 32 секунды
грубая лесть!
почему грубая лесть, просто не круто раз на то пошло -
Май 6, 2012, 4:14 п.п., спустя 1 минуту 22 секунды
Не, не круто! :-) Мало вариантов. И сложно придумать новые (фигуры или цвета) так, чтобы пользователь однозначно понял, о чём спрашивают. -
Май 6, 2012, 4:51 п.п., спустя 36 минут 46 секунд
да, в версии с цветными фигурками вариантов немного. но сложность раскрытия зависит больше от других факторов. есть у меня сайтик куда боты прут как мухи на мед. сейчас там рекаптча и её боты обходят. я попробую эту штуку и доложу смогли ли боты приспособиться )))ιιlllιlllι унц-унц -
Май 6, 2012, 4:59 п.п., спустя 8 минут 38 секунд
artoodetoo, с картинками обойти не проблема по сути, ибо цвета. А вот с вопросами, тот тут для бота уже сложнее, потому в целом отличный вариант каптчи. Ну и, главное, не нужно глаз ломать чтоб разглядеть корявые буквы на цвето-мельтишащем фоне, как частенько бывает у сайтов. Главное вопросы придумать и легкоотвечаемые, но в то же время сложные для бота. -
Май 6, 2012, 5:06 п.п., спустя 6 минут 42 секунды
вот простой способ усиления стойкости каптчи: ввести минимальное время, которое нужно человеку чтобы заполнить форму. зависит от количества полей и от того насколько сложные поля. допустим мы решаем, что реальный человек потратит никак не меньше 5 сек.
<?php
const KEY = 'Some random string';
const NUM_FIGURES = 3;
const MIN_TIMEOUT = 5;
const MAX_TIMEOUT = 300;
const COOKIE_NAME = 'figaptcha';
// …
function __construct($key, $timeoutMin, $timeoutMax)
{
$this->_key = $key;
$this->_timeoutMin = $timeoutMin;
$this->_timeoutMax = $timeoutMax;
}
// …
function check($token, $data, $figaptcha)
{
if (!is_string($figaptcha)
|| !preg_match('%^([^|]+)\|([0-9]+)\|([0-9a-f]+)$%', $figaptcha, $matches)
|| $matches[1] != strval($token)
|| intval($matches[2]) < time()
|| intval($matches[2]) > time() + $this->_timeoutMax - $this->_timeoutMin
) return FALSE;
$x = serialize($data) . '|' . $matches[2];
return hash_hmac('md5', $x, $this->_key) == $matches[3];
}
// …
$figaptcha = new Figaptcha(KEY, MIN_TIMEOUT, MAX_TIMEOUT);
что имеем:
- бот должен представлять алгоритм, он должен понимать, что все чекбоскы это цель для перебора
- фактически сгенерировать правильную куку не зная секретного ключа нереально. то есть бот должен прочесть настоящую куку и использовать её.
- если бот будет быстро перебирать варианты, он обломается, т.к. каптча учитывает мин. таймаут
- если бот будет тормозить, кука просто станет невалидной, т.к. есть макс. таймаутιιlllιlllι унц-унц -
Май 6, 2012, 5:09 п.п., спустя 3 минуты 28 секунд
artoodetoo, если боты так уж прут, то не проще ли на js одно поле в форме сделать? У меня ни на одном сайте капчи нет, и лет 5 как ни одного бота. -
Май 6, 2012, 5:31 п.п., спустя 21 минуту 44 секунды
stopkran, не зарекайся. насчет js я убежденный сторонник «graceful degradation» и считаю, что при обломе с js пользователь может потерять удобство, но не должен потерять возможность.
и вообще кто сказал, что боты не могут использовать js?ιιlllιlllι унц-унц -
Май 6, 2012, 5:43 п.п., спустя 11 минут 56 секунд
if (!is_string($figaptcha)
|| !preg_match('%^([^|]+)\|([0-9]+)\|([0-9a-f]+)$%', $figaptcha, $matches)
|| $matches[1] != strval($token)
|| intval($matches[2]) < time()
|| intval($matches[2]) > time() + $this->_timeoutMax - $this->_timeoutMin
) return FALSE;
заюзай уже sprintf + sscanf :)Спустя 73 сек.и вообще кто сказал, что боты не могут использовать js?
какой нить xrumer, так на иешке работает, там все есть - и ксс1.0(:D) и JSСапожник без сапог -
Май 6, 2012, 6:03 п.п., спустя 19 минут 52 секунды
заюзай уже sprintf + sscanf :)
это как, чото невкуриваю?ιιlllιlllι унц-унц -
Май 6, 2012, 6:05 п.п., спустя 2 минуты 32 секунды
artoodetoo, ну ты создаешь форматированную строку, и потом можешь разобрать ее назад чрез sscanf, а то так уебищно выглядит preg_match + условия в одной каше, прямо аж тошнит)Спустя 41 сек.во я нудный стал, делай чо хочешь :)Спустя 7 сек.стареюСапожник без сапог -
Май 7, 2012, 1:25 п.п., спустя 19 часов 19 минут 22 секунды
Поколдовал со стилями и количеством вариантов.
Как это выглядит в браузере:
Как это выглядит без стилей, т.е. для не шибко умного бота:
2^16 комбинаций. общее количество строк, включая фейковые, задается настройкой
я охуененιιlllιlllι унц-унц
Страницы: ← Следующая страница →
Пожалуйста, авторизуйтесь, чтобы написать комментарий!