При некоторых условиях можно получить данные, хранящиеся в сессии, т.к. она хранится в директории, открытой на чтение-запись с правами веб-сервера, поэтому, если пользователь сможет разместить на этом сервере свой скрипт, то он прочитает все данные, хранящиеся в сессиях пользователей этого веб-сервера.
Но в принципе, я тогда был не прав в некоторых аспектах.
что ж, в этом случае, по итогам нашей беседы с hlomzik, можно сделать след. вывод:
Хранить в сессии необходимо не просто md5-хеш, а md5-хеш с SALT.
В этом случае, даже если бот прочитает данные, то нормальную пару ключ+хеш он не сгенерирует.
Согласен, виноват :).
Большое спасибо за разъяснение, я несколько ошибался в механизме сессий.
Но все-таки, хочу обратить Ваше внимание на одну вещь.
Т.к. данные сессии хранятся на стороне сервера (самому стало стыдно даже, как я столько времени мог думать, что данные сессии сохраняются только в куках) и хранятся они в директории, открытой для чтения записи с правами Web-сервера, обычно в "/tmp".
Как следствие, любой скрипт на этом сервере имеет полный доступ к данным сессии. Поэтому, в том случае, если скрипт-бот установлен на том же сервере, что и атакуемый сайт, или же у него есть часть, которая читает оттуда данные, то при отсутствии шифрования данных мы вполне можем правильно заполнить капчу, прочитав соответствующий файл на сервере.
Повторюсь, это не всегда возможно, а только в том случае, если на тот же хостинг удастся разместить свой скрипт, читающий данные из директории, в которую сохраняются сессии.
Да уж. В соседней ветке меня уже просвятили, что сессия, оказывается, хранится ТОЛЬКО на стороне сервера и поэтому у пользователя нет никакого доступа к данным, сохраненным в ней.
То ли еще будет?
Пожалуйста, прочитайте внимательно. Хешируем с параметром 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 ему неизвестна, то он не сможет сгенерировать правильную пару
//ответ + хеш ответа
Уважаемый, прежде чем писать RTFM рекомендую Вам самостоятельно ознакомиться с понятием сессии.
Итак, что же такое сессия и из чего она состоит? Состоит она из 2х частей.
1. как Вы абсолютно справедливо утверждаете, сессия - это действительно файлик на сервере :). Но здесь есть одно "НО". Этот файлик с именем равным идентификатору сессии, т.е. SID и все. Никаких данных в нем не хранится - Вы сами можете в этом убедиться, если попробуете их посмотреть. Записывается обычно в директорию /tmp, но ее можно изменить.
2. А вот эту часть Вы видимо пропустили :). идентификатор сессии также сохраняется в Cookie пользователя с TTL = 0 :)). В этот же Cookie записываются все необходимые данные. И вот при загрузке след. страницы они передаются серверу. Сервер, в свою очередь, получает идентификатор сессии SID и на основании наличия файлика делает вывод что это за пользователь. Вот так-то.
Кстати, а если у пользователя отключены Cookie? Неужели все ломается? К нашему счастью, нет. Идентификатор сессии дописывается ко все ссылкам на странице. Может, Вы когда-ть замечали ссылки вида "?PHPSESSINID=ewrgfdsjfdjlhgj" - так вот это он и есть.
РЕЗЮМЕ: 1. прежде чем писать RTFM необходимо убедиться, что Вы сами хорошенько разобрались с данным предметом.
2. Доступ у пользователя к данным, хранимым в сессии есть. Поэтому при необходимости их стоит шифровать.
Если будут еще вопросы - прошу писать в личку, давайте не будем здесь разводить флейм.
В дополнение к пред посту. Я уже реально иногда обалдеваю от способности людей усложнять проблемы. Зачем хранить данные от CAPTCH'и в БД?! генерируем ее динамически, запоминаем правильный ответ в виде, нечитаемом для бота в браузере. необязательно даже в сессии, можно и в "самом незащищенном" первом варианте - в скрытом поле. Только храним правильный ответ не в открытом виде, а в md5-хеше. Боимся, что бот сможет подобрать хеш (например, если там банальная картинка из 4х-5ти цифр - вполне реально за разумное время подобрать хеш)? В этом случае испольщуем "соленый" md5 (т.е. шифруем ответ с каким-либо параметром SALT, равным например "gerhsagd ghsdfagf" - попробуй теперь подбери :)).
В общем, ИМХО. Проблема не заслуживает такого усложнения. Зачем делать сложно, когда можно сделать проще? принцип KISS в действии.
в принципе, что мешает записывать данные в сессию пользователя? в крайнем случае, в нее можно записывать md5-хеш правильного ответа, чтобы мега-продвинутые боты не могли прочитать. В итоге к нам придет от юзера md5-хеш правильного ответа и ответ пользователя. Сравниваем - делаем выводы.
И не надо никаких проблем с хранением данных на сервере, с очисткой файлов и т.д., т.к. сессия это по сути банальный Cookie с TTL = 0.
Но в принципе, я тогда был не прав в некоторых аспектах.
Хранить в сессии необходимо не просто md5-хеш, а md5-хеш с SALT.
В этом случае, даже если бот прочитает данные, то нормальную пару ключ+хеш он не сгенерирует.
Большое спасибо за разъяснение, я несколько ошибался в механизме сессий.
Но все-таки, хочу обратить Ваше внимание на одну вещь.
Т.к. данные сессии хранятся на стороне сервера (самому стало стыдно даже, как я столько времени мог думать, что данные сессии сохраняются только в куках) и хранятся они в директории, открытой для чтения записи с правами Web-сервера, обычно в "/tmp".
Как следствие, любой скрипт на этом сервере имеет полный доступ к данным сессии. Поэтому, в том случае, если скрипт-бот установлен на том же сервере, что и атакуемый сайт, или же у него есть часть, которая читает оттуда данные, то при отсутствии шифрования данных мы вполне можем правильно заполнить капчу, прочитав соответствующий файл на сервере.
Повторюсь, это не всегда возможно, а только в том случае, если на тот же хостинг удастся разместить свой скрипт, читающий данные из директории, в которую сохраняются сессии.
То ли еще будет?
В качестве примера.
//определяем константу 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 ему неизвестна, то он не сможет сгенерировать правильную пару
//ответ + хеш ответа
Итак, что же такое сессия и из чего она состоит? Состоит она из 2х частей.
1. как Вы абсолютно справедливо утверждаете, сессия - это действительно файлик на сервере :). Но здесь есть одно "НО". Этот файлик с именем равным идентификатору сессии, т.е. SID и все. Никаких данных в нем не хранится - Вы сами можете в этом убедиться, если попробуете их посмотреть. Записывается обычно в директорию /tmp, но ее можно изменить.
2. А вот эту часть Вы видимо пропустили :). идентификатор сессии также сохраняется в Cookie пользователя с TTL = 0 :)). В этот же Cookie записываются все необходимые данные. И вот при загрузке след. страницы они передаются серверу. Сервер, в свою очередь, получает идентификатор сессии SID и на основании наличия файлика делает вывод что это за пользователь. Вот так-то.
Кстати, а если у пользователя отключены Cookie? Неужели все ломается? К нашему счастью, нет. Идентификатор сессии дописывается ко все ссылкам на странице. Может, Вы когда-ть замечали ссылки вида "?PHPSESSINID=ewrgfdsjfdjlhgj" - так вот это он и есть.
РЕЗЮМЕ: 1. прежде чем писать RTFM необходимо убедиться, что Вы сами хорошенько разобрались с данным предметом.
2. Доступ у пользователя к данным, хранимым в сессии есть. Поэтому при необходимости их стоит шифровать.
Если будут еще вопросы - прошу писать в личку, давайте не будем здесь разводить флейм.
Можно, смотрите Singleton
В общем, ИМХО. Проблема не заслуживает такого усложнения. Зачем делать сложно, когда можно сделать проще? принцип KISS в действии.
И не надо никаких проблем с хранением данных на сервере, с очисткой файлов и т.д., т.к. сессия это по сути банальный Cookie с TTL = 0.
скачать и прочитать документацию можно на http://dklab.ru