Sadda.ru Ironetcart Андроид Ассемблер MASM32 Linux Все статьи Table of Contents


 

Идеальная капча

  Макс Петров Март 2014

Обоснование

      CAPTCHA (от англ. Completely Automated Public Turing test to tell Computers and Humans Apart - полностью автоматизированный публичный тест Тьюринга для различения компьютеров и людей) - компьютерный тест, используемый для того, чтобы определить, кем является пользователь системы: человеком или компьютером. Термин появился в 2000 году, в Рунете устоялось название капча. Основная идея теста: предложить пользователю такую задачу, которую с лёгкостью может решить человек, но которую несоизмеримо сложнее решить компьютеру. CAPTCHA - это товарный знак университета Карнеги - Меллона, разработавшего тест. По состоянию на 2013г., примерно 320 миллионов капч вводится каждый день пользователями во всём мире (из Википедии).

      В тесте CAPTCHA ключевое слово - автоматизированный, предполагается, что один компьютер должен выдать что-то, что другим компьютерам понять никак не дано. Такой компьютер должен быть, похоже, самым умным среди компьютеров. Если же имеется в виду степень умности не компьютера, а программиста, написавшего для компьютера генерящий капчу алгоритм - очевидно, что на каждого сообразительного программиста найдется другой программист, не менее сообразительный. Вообще, когда спамерский робот нападает на капчу, тогда соревнуются ведь две программы (генерящая и распознающая), а если копнуть глубже, то соревнуются два программиста, то есть соревнуются люди, сидящие за компьютерами и пишущие программы. Я не понимаю, где тут противопоставление машины человеку. На мой взгляд, сама идея - создать алгоритм-генератор, результат работы которого будет поддаваться лишь человеческому анализу, но никак не анализу программному - это логическая ошибка.

      Если существует алгоритм, создающий ограниченное число предопределенных (в случае капчи - правилами начертания букв) комбинаций, то всегда можно создать другой алгоритм, распознающий результат работы первого алгоритма. Я не знаю, как сказанное в предыдущем предложении строго доказать, но считаю, что программное распознавание машинно-созданных капч уж точно не является задачей, способной вызвать какие-то принципиальные затруднения. Судите сами. Число букв (округлим) - 30. Число их возможных написаний (наклон вправо, наклон влево, сплющивание, растягивание и пр.) - еще десяток. Провести анализ, из нескольких сотен вариантов выбрать подходящий - это смехотворная задача для сегодняшних вычислительных мощностей.

      Различие человека и компьютера, выгодное для человека, состоит не в быстроте подсчета (здесь компьютер, увы, оказывается сильнее), а в объеме знаний - понятий, ассоциаций, методологий, накопленных каждым человеком, даже молодым, за свою жизнь. Если капча-генератор (программу) можно написать за час, то и распознавалку можно написать примерно за то же время. Однако, невозможно за час научить компьютер тому, что человек узнал за десятилетия жизни. Не по скорости перебора алгоритмических условий человек обыгрывает машину, а по информационному багажу - в способности хранить ассоциативно связанные объемы информации компьютер уступает человеку.

      Для того, чтобы уловить машину на незнании, вопрос должен быть задан машине именно человеком. Вопрос не о видимом на картинке, а о подразумеваемом, т.е. ассоциативно связанном с видимым смысле. Можно пойти еще дальше и заставить поточных роботов-взломщиков соревноваться не с одним человеком даже, а с человеческим сообществом. Сделать это просто - надо принять правилом, что каждый администратор форума должен рисовать свои собственные картинки-вопросы. Растиражированную капчу ломать тем выгоднее, чем больше ее тираж. И наоборот, чем менее конкретный набор картинок с вопросами распространен в Интернете, тем менее оправданными становятся попытки автоматизации его взлома.

      Таким образом, если для сайта нужны действительно надежные капчи, они должны быть смысловыми, вопросы для них должен формулировать человек. Капчи должны быть, по возможности, уникальными (сделанными только для одного сайта). При воплощении такого подхода разработчику следует указать будущим владельцам сайтов правила создания картинок с вопросами. После разработчику останется написать несложный скрипт, который будет встраивать такие самодельные капчи в формы сайта.

Реализация

      Реализация всего этого состоит:
      - из папки captcha, где находятся картинки, выдающий скрипт и др.;
      - фрагмента PHP-кода, встраиваемого в форму;
      - фрагмента PHP-кода, встраиваемого в принимающий POST-данные скрипт.

Содержимое папки captcha


(images - папка с картинками; ip - служебная папка скрипта; captcha.php - скрипт; .htaccess - файл настроек)

Примеры картинок

вода.jpg
зебра.jpg
педаль.jpg

      Картинки содержат вопрос, ответом на который является само имя файла (без расширения) картинки.

Содержимое файла captcha.php (скрипт)

<?php $captchalist = glob(str_replace("\\", "/", dirname(__FILE__)) ."/images/*"); // $captchafilenameurlencode = 0; - не делать кодировку/раскодировку // $captchafilenameurlencode = 1; - кодировать кириллические имена файлов // $captchafilenameurlencode = 2; - раскодировать кириллические имена файлов $captchafilenameurlencode = 0; if ($captchafilenameurlencode === 1) { // кодировать кириллицу for ($i = 0; $i < count($captchalist); $i++) { $fname = $captchalist[$i]; $fname = strrchr($fname, "/"); $fname = str_replace("/", "", $fname); if( !preg_match("/^[a-zA-Z0-9%\. ]+$/", $fname) ) { $captchalist[$i] = "images/" . RawUrlEncode($fname); copy( "images/" . $fname, "images/" . RawUrlEncode($fname) ); unlink("images/" . $fname); } } } if ($captchafilenameurlencode === 2) { // раскодировать кириллицу for ($i = 0; $i < count($captchalist); $i++) { $fname = $captchalist[$i]; $fname = strrchr($fname, "/"); $fname = str_replace("/", "", $fname); if( preg_match("/^[a-zA-Z0-9%\. ]+$/", $fname) ) { $captchalist[$i] = "images/" . rawurldecode($fname); copy( "images/" . $fname, "images/" . rawurldecode($fname) ); unlink("images/" . $fname); } } } $captcharand = ceil(rand(0, count($captchalist)-1 )); $captchaname = $captchalist[$captcharand]; $captchaname = strrchr($captchaname, "/"); $captchaname = str_replace("/", "", $captchaname); $ext = strrchr($captchaname, "."); $captchaname = str_replace($ext, "", $captchaname); $f=fopen("ip/" . $_SERVER["REMOTE_ADDR"] . ".txt","w+"); fwrite( $f, strtolower(rawurldecode($captchaname)) ); fclose($f); readfile("images/" . $captchaname . $ext); exit; ?>

Содержимое файла .htaccess

Options -Indexes <FilesMatch ".(htaccess|jpg|bmp|gif|png)$"> Order Allow,Deny Deny from all </FilesMatch>

PHP-скрипт, встраиваемый в HTML-форму

<?php echo " <a href=# onclick=\"javascript:document.captcha.src='captcha/captcha.php?asd='+Math.random(); return false;\">Обновить</a> <img align=absmiddle name=captcha src=captcha/captcha.php?asd=" . rand() . "> <input type=text maxlength=30 size=40 name=postansw> "; ?>

PHP-скрипт, обрабатывающий введенные пользователем ответы

<?php $filename = "captcha/ip/" . $_SERVER["REMOTE_ADDR"] . ".txt"; if ( !file_exists($filename) ) { echo "ошибка чтения файла"; exit; } if ( file_exists($filename) ) { $answ = file($filename); unlink($filename); if ( trim($answ[0]) !== strtolower($_POST["postansw"]) ) { echo "ответ неверный"; exit; } } // если контрольные цифры введены правильно, то продолжаем выполнение echo "ответ принят"; ?>

      Скачать работоспособный пример (под Денвер) можно здесь.



Ironetcart

      Техническая поддержка: http://ironburattin.ru
      Взять движок: Форум на файлах «Ironetcart» (скачать)

      Разработка форумного движка
      Форум «Железный Бураттин» (название и концепция)
      Статическая защита форм
      Идеальная капча
      Как я победил магические кавычки
      Внеклавиатурные символы HTML
      Хранимые XSS-атаки и защита от них (удаляем javascript из html в браузере)
      Защита визуального html-редактора (фильтрация HTML на стороне сервера)
      Скорость движка форума: файлы или база данных
      Прогресс-бар на PHP
      Зачем тупому форуму поиск?

     


© Max Petrov При использовании материалов ссылка на sadda.ru обязательна