|
|
12.07.2006, 03:53
|
|
Andrew
Зарегистрирован: 2004-04-30
Сообщений: 134
|
На форуме неоднократно поднимался вопрос, касаемый реализации защиты форм картинкой. Кидаю простенькое решение начального уровня. Понятное дело, что защита не ахти какая - фактически от тупого дурака. Однако маловероятно, что кто-то будет сильно корячиться с обходом или писать анализатор специально для вашего уникального веб-проекта В общем, для большинства проектов вполне достаточно.
Реализация, как я уже сказал, максимально простая, что с одной стороны хреново, с другой напротив - антиботовая картинка настраивается как угодно и легко интегрируется в любой дизайн, скрипт коротенький и прозрачненький. Никакие внешние ttf-шрифты, наклоны и повороты букв, а также беспорядочные шумы не используются - всЈ гармонично и геометрически аккуратно (повторюсь, плюсом это, конечно же, не является). Впрочем, все эти надстройки очень просто добавить, прочитав описание библиотеки GD (http://www.boutell.com/gd/) и маны по теме (http://ru.php.net/manual/ru/ref.image.php).
Итак, создаЈм файлик secure.php и кладЈм его в папку netcat (туда же, где лежит vars.ini.php). Содержимое файла такое:
Код:
<?php
// Получаем псевдослучайное число
$rand = rand(10000, 99999);
// Получаем его хэш
$rv = md5($rand);
// Засовываем хэш в куку
setcookie ("RandomValue", $rv);
// СоздаЈм картинку со светло-серой сеткой на тЈмно-сером фоне
$picture = imagecreate (61, 21);
$bgcolor = imagecolorallocate($picture, 165, 165, 165);
$ntcolor = imagecolorallocate($picture, 200, 200, 200);
for ($i=0; $i<=100; $i+=5) imageline($picture, $i, 0, $i, 100, $ntcolor);
for ($i=0; $i<=100; $i+=5) imageline($picture, 0, $i, 100, $i, $ntcolor);
// Случайный цвет для каждой цифры
$fontcolor1 = imagecolorallocate($picture,rand(0,111), rand(0,111), rand(0,111));
$fontcolor2 = imagecolorallocate($picture,rand(0,111), rand(0,111), rand(0,111));
$fontcolor3 = imagecolorallocate($picture,rand(0,111), rand(0,111), rand(0,111));
$fontcolor4 = imagecolorallocate($picture,rand(0,111), rand(0,111), rand(0,111));
$fontcolor5 = imagecolorallocate($picture,rand(0,111), rand(0,111), rand(0,111));
// Рисуем на картинке случайное число
imagestring($picture, 11, 07, 1, substr($rand,0,1), $fontcolor1);
imagestring($picture, 11, 17, 6, substr($rand,1,1), $fontcolor2);
imagestring($picture, 11, 27, 1, substr($rand,2,1), $fontcolor3);
imagestring($picture, 11, 37, 6, substr($rand,3,1), $fontcolor4);
imagestring($picture, 11, 47, 1, substr($rand,4,1), $fontcolor5);
// Посылаем заголовки и картинку
header("Content-type: image/png");
imagepng($picture);
imagedestroy($picture);
?>
В тестовом шаблоне используются 2 поля - Контактное лицо и Электронная почта. Т.е. получаем что-то типа примитивной подписки на новости (для демонстрации большего и не требуется). Поле Альтернативная форма добавления принимает примерно такой вид:
Код:
".opt($warnText,"<p>Ошибка! $warnText</p>")."
".opt($rv = $_COOKIE['RandomValue'],"")."
".opt($uv = md5($f_Number),"")."
<div style='position:absolute; background-color:#f8f8f8; padding:15px;'>
<form name='adminForm' method='post' action='/netcat/add.php'>
<input type='hidden' name='cc' value='$cc' />
<input type='hidden' name='sub' value='$sub' />
<input type='hidden' name='catalogue' value='$catalogue' />
<input type='hidden' name='posting' value='1' />
<h2>Subscription</h2>
<p>Contact Persone:<br />
<input type='text' size='30' maxlength='255' name='f_Name' value='' /></p>
<p>Your E-mail:<br />
<input type='text' size='30' maxlength='255' name='f_Email' value='' /></p>
<p>Antibot Secure:<br />
<input type='text' size='19' maxlength='5' name='f_Number' value='' />
<img src='/netcat/secure.php' width='61' height='21' align='absmiddle' /></p>
<p style='text-align:center;'><input value='Отправить' type='submit' /></p>
</form>
</div>
И ещЈ дописываем в поле Условия добавления объекта соответствующую проверку:
Код:
if ($_COOKIE['RandomValue'] != md5($f_Number))
{
$warnText="I hate bots!";
$posting=0;
}
Или для наглядности:
Код:
if ($_COOKIE['RandomValue'] != md5($f_Number))
{
$warnText="Значениe ".$_COOKIE['RandomValue']." не равно ".md5($f_Number)."!";
$posting=0;
}
Вот и всЈ! Кажется ничего не забыл 
Если у кого появятся свои варианты - предлагайте. Может быть совместными усилиями выработаем какое-то универсальное решение, пригодное для включения в стандартную поставку системы - в конце концов у меня проблема защиты возникла только однажды и этот скрипт еЈ решил. Кстати, я буду особенно рад решениям, основанным на сессиях, бо у меня ничего не получилось, как ни старался. А с куками нормально работает.
...жизнь прекрасна, когда правильно подобраны антидепрессанты...
|
|
|
12.07.2006, 11:27
|
|
DiGGy
DiGGy

Зарегистрирован: 2005-04-04
Сообщений: 1546
|
имхо, RandomValue не обязательно в куку запихивать, его можно вывести как <input type='hidden' name='RandomValue' value='$rv' />
все равно никто не знает как Вы это значение сгенерировали.. либо md5(x), либо md5(md5(x)), либо как угодно еще... куки не у всех должны быть включены, значит и не все запостят инфу..
на счет сессий - тут тоже ничего сложного, алгоритм работы можете посмотреть в движке неткета - там есть возможность авторизации через сессии
зы: а так решение стандартное, какое и всем предлагалось... людям остается только разобраться как настроить GD
Temet nosce...
|
|
|
12.07.2006, 11:41
|
|
Сергей Сморовоз
Визуальный Маркетинг - SL-System

Зарегистрирован: 2005-03-04
Сообщений: 83
|
DiGGy писал(а):на счет сессий - тут тоже ничего сложного, алгоритм работы можете посмотреть в движке неткета - там есть возможность авторизации через сессии
Заливать код в таблицу сессий?
DiGGy писал(а):зы: а так решение стандартное, какое и всем предлагалось... людям остается только разобраться как настроить GD
А где предлагалось? Можно ссылку. Мне как раз тоже нужна защита.
Аудит сайтов на CMS NetCat, SEO оптимизация и поисковое продвижение.
|
|
|
12.07.2006, 11:57
|
|
Гость
Зарегистрирован: 1970-01-01
Сообщений: 665
|
Метод называется обратным тестом Тьюринга.
http://netcat.ru/dealers/advice/function/function_67.html
вынес сюда для будущих поколений.
|
|
|
12.07.2006, 14:59
|
|
DiGGy
DiGGy

Зарегистрирован: 2005-04-04
Сообщений: 1546
|
Dr_Jeans писал(а):Заливать код в таблицу сессий?
Не очень понял какой именно код и в какую именно таблицу сессий.
При старте сессий генериться уникальный идентификатор сесии в 128 бит. По умолчанию на сервере хостера создается файлик с именем включающим этот идентификатор (имя файла и его расположение можно менять...). Если не хотите создавать файл, то есть возможность запихивать идентификатор, например, в табличку базы данных.
В данном примере предполагалось хранить переменную RandomValue не в куке, а в файле сессии. Но тут встанет другой вопрос - как передавать идентификатор сессии:
- либо через туже самую куку
- либо через добисание идентификатора в урлы сайта
- либо создать скрытую переменную, типа: <input type='hidden' name='sid' value='$sid'>
зы: если я че не так понял по вашему вопросу - извиняйте...
Dr_Jeans писал(а):А где предлагалось? Можно ссылку. Мне как раз тоже нужна защита.
На этом форуме неоднакратно такие вопросы были - поищите
Temet nosce...
|
|
|
12.07.2006, 21:20
|
|
diawest
Зарегистрирован: 2006-01-20
Сообщений: 6
|
Это не серьезный подход. Любой злоумышленник увидев сайт на неткате, будет пытаться пробить его таким подходом. Сделайте хотя бы так:
$passphrase = 'наш секретный пароль для хэша, поменяйте для своего сайта!';
$rv = md5(md5($rand).$passphrase);
И вот такой хэш передавайте клиенту, лучше все-таки через <input type='hidden' />, т.к. куки действительно могут быть отключены. Такая схема по крайней мере дает элементарную степень защиты от тех, кто может заглянуть в "Советы и приемы" и разгадать схему генерации хэша.
И еще подумалось, человек же может один раз посмотреть какое число на картинке, какой хэш в куке и заставить робота подставлять эту пару для всех-всех-всех сообщений. Значит кроме $passphrase финальный хэш должен иметь часть, меняющуюуся со временем. Например, номер текущего дня в году + количество 15-минутных интервалов с начала суток. Можно еще IP клиента к хэшу добавлять...
NetCat CMS Certified Developer ;) http://www.specialist.ru?public=295096
|
|
|
13.07.2006, 09:14
|
|
Гость
Гость
|
Тут речь идет не о злоумышленниках, а о спам-ботах и элементарной защите от них.
Ясен пень, что сделать 100% защиту от злоумышленников вообще не получится!
Если Вы хорошо разбираетесь в технологиях и изучили движок неткета, то Вы уже являетесь потенциальным злоумышленником! И 100% гарантии, что сайт не ломанут Вам никто не даст!
Вероятность лома можно сводить к минимуму всякими алгоритмами аналогичными Вашему, но как грится - совершенству нет предела... и на каждый Ваш алгоритм можно навоять другой алгоритм и т.д. независимо от серьезности Вашего подхода.
|
|
|
13.07.2006, 11:31
|
|
Гость
Зарегистрирован: 1970-01-01
Сообщений: 665
|
Мы не публикуем руководство к действую в Советах и приемах, а лишь различные варианты решения той или иной проблемы. Степень доработки описанного лежит на ваших плечах.
|
|
|
13.07.2006, 19:24
|
|
Сергей Сморовоз
Визуальный Маркетинг - SL-System

Зарегистрирован: 2005-03-04
Сообщений: 83
|
DiGGy писал(а):Dr_Jeans писал(а):Заливать код в таблицу сессий?
Не очень понял какой именно код и в какую именно таблицу сессий.
При старте сессий генериться уникальный идентификатор сесии в 128 бит. По умолчанию на сервере хостера создается файлик с именем включающим этот идентификатор (имя файла и его расположение можно менять...). Если не хотите создавать файл, то есть возможность запихивать идентификатор, например, в табличку базы данных.
В данном примере предполагалось хранить переменную RandomValue не в куке, а в файле сессии. Но тут встанет другой вопрос - как передавать идентификатор сессии:
- либо через туже самую куку
- либо через добисание идентификатора в урлы сайта
- либо создать скрытую переменную, типа: <input type='hidden' name='sid' value='$sid'>
Файл сессий - это уже перебор!
В большинстве форумов, phpBB подобных, под сессии пользователя
создаЈтся запись в таблице сессий, в которой и хранятся все
аналогичные вещи.
Аудит сайтов на CMS NetCat, SEO оптимизация и поисковое продвижение.
|
|
|
13.07.2006, 21:52
|
|
Гость
Гость
|
Dr_Jeans писал(а):
Файл сессий - это уже перебор!
В большинстве форумов, phpBB подобных, под сессии пользователя
создаЈтся запись в таблице сессий, в которой и хранятся все
аналогичные вещи.
По дефолту, как писал Diggy, php-сессии хранятся во временном файле в папке /tmp/ (все переменные, доступные из массива $_SESSIONS). В NetCat это реализовано точно так же, поэтому создание таблицы как раз и будет перебором))
DiGGy писал(а):
Но тут встанет другой вопрос - как передавать идентификатор сессии:
- либо через туже самую куку
- либо через добисание идентификатора в урлы сайта
- либо создать скрытую переменную, типа: <input type='hidden' name='sid' value='$sid'>
Насколько я помню, NetCat не поддерживает передачу session_id через куки, только жестко через POST & GET. А скрытое поле и так автоматически добавится во все формы, найденные на странице, не подставляется только в header(). Поэтому, если использовать куки для передачи идентификатора сессий - вполне возможно, что система будет конфликтовать с этим...
|
|
|
14.07.2006, 09:36
|
|
DiGGy
DiGGy

Зарегистрирован: 2005-04-04
Сообщений: 1546
|
d писал(а):Насколько я помню, NetCat не поддерживает передачу session_id через куки, только жестко через POST & GET. А скрытое поле и так автоматически добавится во все формы, найденные на странице, не подставляется только в header(). Поэтому, если использовать куки для передачи идентификатора сессий - вполне возможно, что система будет конфликтовать с этим...
Да, Вы правы, но в данном топике речь идет лишь о защите формочки, и представленное решение приведено с учетом только этих требований... о задействовании всего механизма авторизации через сессии я не говорил, просто локально для этой формочки можно стартовать сессию... ясен пень, что это геморно, но это нельзя не рассматривать как один из вариантов.
Temet nosce...
|