Регистрация
Вход через соцсети
Восстановление пароля

Защита форм картинкой

Новый топик
Страницы: 1  |  2
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='' />&nbsp;
<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
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
Ответить | Цитировать
drjeans
Сморовоз Сергей
drjeans

Зарегистрирован:
2005-03-04
Сообщений: 76

DiGGy писал(а):
на счет сессий - тут тоже ничего сложного, алгоритм работы можете посмотреть в движке неткета - там есть возможность авторизации через сессии

Заливать код в таблицу сессий?
DiGGy писал(а):
зы: а так решение стандартное, какое и всем предлагалось... людям остается только разобраться как настроить GD

А где предлагалось? Можно ссылку. Мне как раз тоже нужна защита.

Аудит сайтов на CMS NetCat, оптимизация и поисковое продвижение.
12.07.2006, 11:57
Ответить | Цитировать
Гость

Зарегистрирован:
1970-01-01
Сообщений: 665

Метод называется обратным тестом Тьюринга.

http://netcat.ru/dealers/advice/function/function_...
вынес сюда для будущих поколений.
12.07.2006, 14:59
Ответить | Цитировать
DiGGy
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
Ответить | Цитировать
drjeans
Сморовоз Сергей
drjeans

Зарегистрирован:
2005-03-04
Сообщений: 76

DiGGy писал(а):
Dr_Jeans писал(а):
Заливать код в таблицу сессий?

Не очень понял какой именно код и в какую именно таблицу сессий.

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

В данном примере предполагалось хранить переменную RandomValue не в куке, а в файле сессии. Но тут встанет другой вопрос - как передавать идентификатор сессии:
- либо через туже самую куку
- либо через добисание идентификатора в урлы сайта
- либо создать скрытую переменную, типа: <input type='hidden' name='sid' value='$sid'>

Файл сессий - это уже перебор!
В большинстве форумов, phpBB подобных, под сессии пользователя
создаЈтся запись в таблице сессий, в которой и хранятся все
аналогичные вещи.

Аудит сайтов на CMS NetCat, оптимизация и поисковое продвижение.
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
DiGGy

Зарегистрирован:
2005-04-04
Сообщений: 1546

d писал(а):
Насколько я помню, NetCat не поддерживает передачу session_id через куки, только жестко через POST & GET. А скрытое поле и так автоматически добавится во все формы, найденные на странице, не подставляется только в header(). Поэтому, если использовать куки для передачи идентификатора сессий - вполне возможно, что система будет конфликтовать с этим...


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

Temet nosce...
198 196 2008-03-10 22:28:14 6867
Страницы: 1  |  2
Описание проекта