Pull to refresh

Comments 32

Извините, уже исправил :-) .
UFO just landed and posted this here
Ну вот... сначала вы удаляете рисунки SQL-запросами, скоро будете форматировать винт html-тегами :)

Я надеюсь, Вы же не хотите сказать, что храните рисунки в БД и возвращаете их php-скриптом? :)

По поводу эээ, хм, "трех основных способов сохранения данных CAPTCHA": вот вам четвертый, один из наиболее очевидных и распространенных(если не самый) — тупо писать в файл :)
А то веб-программисты со своими СУБД уже совсем забыли, что существуют просто файловые системы :)
Я это говорю только к тому, что люди забывают ростые вещи, не подумайте ничего более, я конечно же понимаю все преимущества современных СУБД
Кстати, я сам веб-программист :) И пардон за опечатки в предыдущем комментарии.
Не, рисунки в БД я не предлагал :-)
а как же поле pic_name?
в ваших 2-м и 3-м варианте файлики скапливаться все равно будут...
только вот пожалуйста, опишите процесс получения самой капчи и объясните, нужны ли там файлы изображений?
в этом поле должно храниться имя файла с рисунком. для удаления - unlink().
для создания самой captcha можно использовать либо какую-нибудь графическую библиотеку (вроде GD), либо готовые файлы (например, если посетитель должен выбрать один из нескольких предложенных)
если использовать готовые файлы, то остро встает проблема их выкачивания ботом и предварительной идентификации
т.е. минусы:
- конечное число вариантов
- прямой доступ к конкретной капче
я имел ввиду, что готовые файлы можно использовать в каптче типа:
"Выберите картинки с живой природой", и после этого несколько случайных картинок (так, чтобы вероятность угадывания была достаточно низкой).
да, я понимаю, о чем вы
этот вопрос уже пару раз обсуждался (тут подборка например)
этот набор картинок живой природы быстро скачивается и за небольшое время рассортировывается живым человеком, после чего бот всегда будет безошибочно проходить тест до следующей смены теста...
спасением конечно может быть огрмный набор картинок или частая смена этого набора
в принципе, что мешает записывать данные в сессию пользователя? в крайнем случае, в нее можно записывать md5-хеш правильного ответа, чтобы мега-продвинутые боты не могли прочитать. В итоге к нам придет от юзера md5-хеш правильного ответа и ответ пользователя. Сравниваем - делаем выводы.
И не надо никаких проблем с хранением данных на сервере, с очисткой файлов и т.д., т.к. сессия это по сути банальный Cookie с TTL = 0.
в нее можно записывать md5-хеш правильного ответа, чтобы мега-продвинутые боты не могли прочитать

ух, спасибо, посмеялся))
rtfm session, session.save_handler etc.
я не понял смысла комментария. Над чем посмеялись? Вы сомневаетесь в том, что в сессии пользователя можно сохранять свои данные?
я уверен в том, что в самой сессии нет смысла что-то шифровать, потому что к этим данным у пользователя (бота) доступа быть не может по определению
Уважаемый, прежде чем писать RTFM рекомендую Вам самостоятельно ознакомиться с понятием сессии.
Итак, что же такое сессия и из чего она состоит? Состоит она из 2х частей.
1. как Вы абсолютно справедливо утверждаете, сессия - это действительно файлик на сервере :). Но здесь есть одно "НО". Этот файлик с именем равным идентификатору сессии, т.е. SID и все. Никаких данных в нем не хранится - Вы сами можете в этом убедиться, если попробуете их посмотреть. Записывается обычно в директорию /tmp, но ее можно изменить.
2. А вот эту часть Вы видимо пропустили :). идентификатор сессии также сохраняется в Cookie пользователя с TTL = 0 :)). В этот же Cookie записываются все необходимые данные. И вот при загрузке след. страницы они передаются серверу. Сервер, в свою очередь, получает идентификатор сессии SID и на основании наличия файлика делает вывод что это за пользователь. Вот так-то.
Кстати, а если у пользователя отключены Cookie? Неужели все ломается? К нашему счастью, нет. Идентификатор сессии дописывается ко все ссылкам на странице. Может, Вы когда-ть замечали ссылки вида "?PHPSESSINID=ewrgfdsjfdjlhgj" - так вот это он и есть.
РЕЗЮМЕ: 1. прежде чем писать RTFM необходимо убедиться, что Вы сами хорошенько разобрались с данным предметом.
2. Доступ у пользователя к данным, хранимым в сессии есть. Поэтому при необходимости их стоит шифровать.

Если будут еще вопросы - прошу писать в личку, давайте не будем здесь разводить флейм.
Ух ты )
Нет, извините, но такую ужаснейшую дезинформацию оставлять в публичном месте безответной нельзя ни в коем случае. Мало того, что такое уверенное высказывание глупостей оскорбляет меня лично, так это вредно любому новичку заглянувшему сюда (а судя по треду, их тут есть ;) )
Для начала прошу сюда — http://phpfaq.ru/sessions
Если вы не доверяете уважаемому мною phorror'у, то прошу сюда — http://www.php.net/manual/ru/ref.session…
Приведу здесь первейшие же абзацы:
A visitor accessing your web site is assigned a unique id, the so-called session id. This is either stored in a cookie on the user side or is propagated in the URL.

The session support allows you to register arbitrary numbers of variables to be preserved across requests. When a visitor accesses your site, PHP will check automatically (if session.auto_start is set to 1) or on your request (explicitly through session_start() or implicitly through session_register()) whether a specific session id has been sent with the request. If this is the case, the prior saved environment is recreated.

из которых при минимальном знании английского будет уяснен абстрактный механизм сессий. Так как язык у нас server-side, то и информацию храним мы на все той же серверной стороне, не особенно важно, где. При этом нам нужно идентифицировать пользователя, для чего мы генерируем уникальный идентификатор пользователя, который и передаем ему. После этого пользователь будет на каждой итерации взаимодействия с сервером передавать каким-либо образом этот идентификатор, а сервер в ответ будет восстанавливать сессионные данные.
В реализации PHP идентификатор передается туда-обратно с помощью кук, а при их отключении сервер включает sess_id в ответ, дополняя ссылки лишним параметром, а формы - лишним скрытым полем, доставая их при запросе из $_GET и $_POST массивов. В случае капчи есть небольшая проблема, так как к src ничего не добавляется, но, думается мне, вызвать session_id() при генерации кода кратинки не составит труда, что позволит и скрипту генерации капчи понимать, кто ее трогает...

Знаете, не всегда легко писать такие большие посты, особенно расписывая в них основы. Особого желания повторять подобный подвиг может не появиться. Так что, пожалуйста, не утруждайте меня больше глупостями, а пройдите по ссылкам, рассмотрите примеры и попробуйте сами. И все станет яснее.
Согласен, виноват :).
Большое спасибо за разъяснение, я несколько ошибался в механизме сессий.
Но все-таки, хочу обратить Ваше внимание на одну вещь.
Т.к. данные сессии хранятся на стороне сервера (самому стало стыдно даже, как я столько времени мог думать, что данные сессии сохраняются только в куках) и хранятся они в директории, открытой для чтения записи с правами Web-сервера, обычно в "/tmp".
Как следствие, любой скрипт на этом сервере имеет полный доступ к данным сессии. Поэтому, в том случае, если скрипт-бот установлен на том же сервере, что и атакуемый сайт, или же у него есть часть, которая читает оттуда данные, то при отсутствии шифрования данных мы вполне можем правильно заполнить капчу, прочитав соответствующий файл на сервере.
Повторюсь, это не всегда возможно, а только в том случае, если на тот же хостинг удастся разместить свой скрипт, читающий данные из директории, в которую сохраняются сессии.
В дополнение к пред посту. Я уже реально иногда обалдеваю от способности людей усложнять проблемы. Зачем хранить данные от CAPTCH'и в БД?! генерируем ее динамически, запоминаем правильный ответ в виде, нечитаемом для бота в браузере. необязательно даже в сессии, можно и в "самом незащищенном" первом варианте - в скрытом поле. Только храним правильный ответ не в открытом виде, а в md5-хеше. Боимся, что бот сможет подобрать хеш (например, если там банальная картинка из 4х-5ти цифр - вполне реально за разумное время подобрать хеш)? В этом случае испольщуем "соленый" md5 (т.е. шифруем ответ с каким-либо параметром SALT, равным например "gerhsagd ghsdfagf" - попробуй теперь подбери :)).
В общем, ИМХО. Проблема не заслуживает такого усложнения. Зачем делать сложно, когда можно сделать проще? принцип KISS в действии.
как насчет ответа от пользователя, когда он посылает заведомо верный ключ и хеш?
Пожалуйста, прочитайте внимательно. Хешируем с параметром SALT. Этот параметр пользователь не знает, т.к. он хранится скрыто на сервере.
В качестве примера.

//определяем константу SALT
define('SALT', '3jhfjshdhu324rHDGhj');

//правильный ответ в капче
$rightAnswer = '12345';
//печатаем 827ccb0eea8a706c4c34a16891f84e7b
print md5($rightAnswer) . "\r\n";

//теперь же шифруем с SALT, получаем 112e5f56db5bffaf539fe6d55eb7ad42
//это совсем другой хеш, не правда ли?
print md5(SALT .$rightAnswer) . "\r\n";

//теперь рассматриваем ситуацию - пользователь ввел пару
// ответ
$userAnswer = '98765';
// и его md5-хеш c37bf859faf392800d739a41fe5af151
print(md5($userAnswer)) . "\r\n";
//если сравнивать без параметра SALT, то действительно получится, что юзеру удалось обойти капчу
//т.к. md5($userAnswer) == 'c37bf859faf392800d739a41fe5af151'
//но проверка-то на сервере проходит след образом, сравниваются с md5-хешом не md5($userAnswer), а
print md5(SALT . $userAnswer);//338d3b066e69cc518e7eb40cbc623227
//Этот хеш совсем не похож на хеш, присланный пользователем
//и т.к. константа SALT ему неизвестна, то он не сможет сгенерировать правильную пару
//ответ + хеш ответа
да нет же.

я могу пройти один раз такую каптчу вручную, узнать таким образом любую пару ключ+хеш, и всегда посылать её в ответ. и он будет верен.

менять salt вы можете, но она все равно будет валидна в течении некоторого времени. вопрос - насколько часто вы готовы её менять?
что ж, в этом случае, по итогам нашей беседы с hlomzik, можно сделать след. вывод:
Хранить в сессии необходимо не просто md5-хеш, а md5-хеш с SALT.
В этом случае, даже если бот прочитает данные, то нормальную пару ключ+хеш он не сгенерирует.
а если задать salt вида date(TZaADdFFjIM)?

Он будет меняться каждые сутки автоматически.
Я, конечно, не программер. Так, в качестве хобби мучаю "Вордпресс". Но тут вот у меня одна мысль. Просто генерить картинку, а слово кодовое — шифровать SHA-256, например. И потом передавать хэш на комп пользователя в скрытом поле.

Далее юзер вводит слово, а оно на сервере хэшируется, и его хэш сравнивается с хэшем, созданным при генерации "капчи".

Мне кажется, это оптимальный вариант. И по безопасности, и по быстродействию, и не надо мороки с БД, сессиями.
Добавлю свою копеечку:

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

- Для вывода капчи можно (а может даже и лучше) генерить картинку "на лету", так как она в 99% будет использована только один раз.
Если никто не против, попробую ответить сразу на все предыдущие комментарии.

Насчет БД я согласен - для обычной captcha перебор :-) . Но, последнее время начали появляться оригинальные варианты captcha, которые требуют использования БД (например, maxsite.org/antispam2), поэтому этот вариант я и рассматривал.

Что касается передачи данных в скрытом поле с использованием md5 (или другого алгоритма хеширования). Если при этом не использовать параметры SALT (как предлагает arbyte), то спамер сможет отправить свой ответ и md5 сумму в скрытом поле, рассчитанную по его значению.

А вообще, в последнее время я столкнулся со спамом, оставленным людьми. Есть даже сервисы, которые за это платят :-( . Так что есть подозрение, что скоро придется пересматривать весь подход к captcha.
Черт, люди, о чем вы?!
Генерируется пара ответ-капча, ответ сохраняется в сессии, слышите, в сессии - это в большинстве случаев маленькие файлики на стороне сервера.
Пользователь (бот) может только самостоятельно получить ответ по капче, перехват невозможен.
При этом в случае с картинками капча - отдельный запрос, запрос к срипту, потому как промежуточное сохранение капчи в файл избыточно...
UFO just landed and posted this here
К сожалению, автор не копенгаген в теме. У нас в компании это называется говнокодерством. Без обид.
UFO just landed and posted this here
Мда, если честно проблема выосана из пальца :) Та хранишь данные в сессии :) а картинку генеришь динамически (при этом её никуда сохранять не нужно), текст для картинки берёшь из той же сессии :)
Мда А тут прямо научная работа :))))
Sign up to leave a comment.

Articles