Ламерский вопрос по безопасности сессий

Merk

Guest
Ламерский вопрос по безопасности сессий

Помогите, плиз новичку

Делаю интернет-магазин. При регистрации пользователя все его данные записываются в БД + генерится для него уникальный код и записывается туда же. Реализация сессий сделана вручную - > в каждой ссылке передается этот самый уникальный номер по типу
"stuff.php?uid=435njlkjdsfiuy45oydfnm"

Вопрос в том, как и что нужно чистить по завершении сессии,?

А то ведь даже в истории ссылок в браузере остаются ссылки с uid... да и в Temporary Internet Files...и ещё где-то наверное.
И это не есть хорошо. При условии, что компом юзера пользуются сто разных людей, к примеру, так вообще катастрофа... Разъясните, пожалуйста, прежде чем босс на шнурки пустит
 

Кром

Новичок
Собственно говоря, если ты решил держать весь процес под полным контролем и все хранить в базе нет ничего проще.
1. Сделай кнопку выход и при нажатии на нее чисти сессию в базе.
2. В базе, для каждой сессии пиши время обновления страницы. Если оно больше, скажем, 10 минут, убивай сессиию и требуй повторной авторизации.
 

Merk

Guest
О! Спасибо! Действительно просто и в точку.

Попутно возник вопрос...
Когда юзер вводит свои логин и пароль в форму, даже POST ведь можно перехватить. Какова вероятность?

И ещё...Процесс авторизации у меня проходит примерно так:

mysql_connect();
$sql = "select * from users where user_name = '$user_name' && user_password = '$user_password';";

if ($result = mysql_db_query("database","$sql"))
{
$row = mysql_fetch_object($result);
Header ("Location: index.php?uid=$row->user_uid");
}
else
{
echo "Wrong username or password!";
exit;
}

Есть более безопасные методы проверки или этот пригоден для пользования?
 

Кром

Новичок
В прстом виде передача зашифрованного пароля:
http://phpclub.ru/talk/showthread.php?s=&threadid=37434&rand=3
В более сложном лучше использовать https. Тем на форуме было предостаточно - в поиск.

Авторизация совершенно нелепа. Ищи опять таки по форуму.
Тема поднималась неоднократно.
Когда скрипт авторизации станет более осмысленным и возникнут вопросы, задавай.
 

Merk

Guest
Автор оригинала: Кром
В прстом виде передача зашифрованного пароля:
С этим понял и разобрался. Пофиксено.

Автор оригинала: Кром
Авторизация совершенно нелепа. Ищи опять таки по форуму.
Тема поднималась неоднократно.
Когда скрипт авторизации станет более осмысленным и возникнут вопросы, задавай.
:confused: В общем, важен не сам скрипт - это был только пример, написанный за 5 сек...(рабочий, кстати)
К тому же это была только та часть, что проверяет, есть ли такой юзер и пароль или нет, всё остальное делается за кадром.

И, кстати, сейчас убил полночи, ковыряясь на форуме по этой теме....Чем конкретно нелепа, кроме корявой проверки на true-false? Это-то можно за 5 сек. поменять. Интересует другое - то, что я достаю пароль из базы и сравниваю его с полученным из формы и расшифрованным - это можно где-то перехватить? Или можно спать спокойно? :) Я понимаю, что всезнающих пхп гигантов могут бесить мои вопросы, но я сюда пишу, чтобы объяснили...

И вот что интересно: в БД лучше держать пароль зашифрованным или нет? Тогда его не придется даже расшифровывать каждый раз при проверке.
 

Developer

Guest
Стандартное решение:
1. Создаешь модуль для обработки логина. На вход поступает имя пользователя и пароль.
$res = mysql_query("select * from users where name=$uname and pass=$upass");
Не буду писать все, поскольку это тривиально... если есть возвращенные записи, логин успешный, мы запоминаем в той же таблице текущее время и сгенерированный идентификатор сессии. Если нет записей, die ... В конце модуля - Header ("Location: index.php?SID=$sid&UID=$uid");
2. Создаешь модуль для проверки сессии. Его нужно инклудить сверху каждго модуля, который требует авторизованного доступа. В этом модуле проверяешь идентификатор сессии данного пользователя и время прошедшее с последнего обращения (таймаут). Если идентификатор совпадает и таймаут не вышел, все в порядке, обновляем в таблице время последнего доступа. Если что-то не так, die. Время при сравнении нужно всегда брать из одного источника (или из php или из MySQL ибо они могут отличаться).
 

Фанат

oncle terrible
Команда форума
Интересует другое - то, что я достаю пароль из базы и сравниваю его с полученным из формы и расшифрованным
стоп.
не ты ли писал ДО этого, что у тебя все
С этим понял и разобрался. Пофиксено.
слово "расшифрованным" говорит о том, что ты совершенно не понял, о чем говорится в ссылке, которую тебе дали.

А теберь скажи мне - какой смысл тебе что-то отвечать, если ты не читаешь УЖЕ данных тебе ответов? А отвечаешь, что "разобрался"?
Всезнающих гигантов пхп бесит не незнание и не вопросы, а то, что когда на вопрос отвечаешь, ответ остается без внимания.
Чем конкретно нелепа
И это человек, который парится по поводу перехвата логина с паролем (какого перехвата? где? Чего перехвата? Похоже, он сам не очень понимает, а просто где-то слышал) - этот человек при этом пишет авторизацию, при которой ЛЮБОЙ вася с улицы ДАЖЕ НЕ ПЕРЕХВАТЫВАЯ просто введет адрес в своем браузере index.php?uid=xxxx
и запросто авторизуется!
Не говоря уже о перехвате этого уида!

И вот что интересно: в БД лучше держать пароль зашифрованным или нет? Тогда его не придется даже расшифровывать каждый раз при проверке.
пол-ночи ты провел совершенно зря.
пароль хранится зашиврованным односторонне и не расшиыровывается. проведи теперь пол-дня за чтением md5
 

Developer

Guest
2 Фанат

По сути все верно.
Но, любезный, зачем такой апломб и откуда такое самомнение?
Нельзя ли чуть поменьше эмоций?
Такое впечатление, что ВЫ отвечая в форуме, выполняете давно надоевшую и нелюбимую работу...
 

Merk

Guest
Автор оригинала: Фанат
слово "расшифрованным" говорит о том, что ты совершенно не понял, о чем говорится в ссылке, которую тебе дали.
Хм...Объясню...У меня принцип выглядит так...На странице index.php есть форма с user, pass. Форма отсылает данные на страницу auth.php, которая проверяет в БД есть ли такие имя и пароль или нет. Если есть - возвращает обратно на index.php?uid=bla-bla-bla, предварительно записав его в базу вместе со временем. Если нет - посылает обратно на index.php?uid=40. Каждому анонимному пользователю позволяется бродить по страницам с некоторыми частичными исключениями. Им при входе присваивается id скажем 40.

На каждой странице, требующей авторизации в начале стоит проверка uid из базы (и как мне уже тут подсказали дата последнего вызова).

Автор оригинала: Фанат
***наезды вырезаны***
при которой ЛЮБОЙ вася с улицы ДАЖЕ НЕ ПЕРЕХВАТЫВАЯ просто введет адрес в своем браузере index.php?uid=xxxx
и запросто авторизуется!
Не говоря уже о перехвате этого уида!
Да? Каким же образом, если стоит проверка в начале каждой страницы? Ты сможешь подделать зашифрованный случайно сгенерированный uid из знаков так 30-ти? Сколько лет у тебя на это уйдет? А если прибавить сюда защиту от слишком частого вызова страницы и обновление uid на каждую сессию... Дай-ка мне этого Васю с улицы :) Про перехват...я уид и не скрываю, передаю по типу GET в каждой ссылке. Для того он и был, собственно придуман.

Автор оригинала: Фанат пол-ночи ты провел совершенно зря.
пароль хранится зашиврованным односторонне и не расшиыровывается. проведи теперь пол-дня за чтением md5
Тут я думал о двух возможных решениях...
1. Хранить в БД пароль в обычном своём текстовом виде. Шифровать перед пересылкой пароль, введенный юзером в форму. Расшифровывать его скриптом-получателем и сверять с оригиналом в БД.

2. Хранить в БД зашифрованный пароль. И сверять его с зашифрованным же вариантом, пришедшим через форму.

To Developer
А обязательно добавлять ещё и SID? uid, как мне кажется, вполне достаточно...
 

Developer

Guest
ГМ :))

Это вопрос терминологии...
UID - идентификатор пользователя. Он жестко закреплен за пользователем и не меняется никогда. Задается при регистрации пользователя (логично использовать в качестве UID первичный ключ таблицы)
SID - временный идентификатор сессии. Генерируется при каждом логине пользователя. Имеет, как правило, небольшой срок жизни 10 мин - 1 сут.
 

Merk

Guest
Re: ГМ :))

To Developer

Ну, я его просто так назвал uid, что подразумевало не user ID, а unique ID :) А user_ID из таблицы используется у меня для других целей и несет в себе порядковый номер юзера в оной.

PS: Спасибо за помощь.
 

Кром

Новичок
Merk, ты действительно, старайся называть вещи своими имена. То у тебя UID = 40, то это уникальный идентификатор из 30 знаков.
В терминах, как уже подмечено ты запутался и путаешь остальных.
Пароль в базе храни в зашифрованном виде.

Developer, тебе я настоятельно рекомендую почитать что нибудь про SQL injection.
 

Developer

Guest
2 Кром

Я в курсе. Но последнии версии php автоматически обрабатывают импортированные переменные, и addcslashes можно не вызывать :)
Поясни, кстати, зачем шифровать пароль в базе? имхо, когда злоумышленник получил доступ к базе, шифрование пароля мало что может дать...
 

Merk

Guest
Кром, uid принимает значение 40 только в случае, если это не зарегистрированный пользователь, который хочет просмотреть страницы требующие идентификации. При uid=40 на этих страницах некоторые возможности становятся недоступными. Заказ товаров, например. Во всех остальных случаях это идентификатор из 30 знаков.

Кстати, я тут задумался. А кто может ткнуть носом в то, как зашифровать пароль ПЕРЕД отправкой формы? Примерно представляю себе, что это связано с JS, но придумать принцип что-то не получается. Это так, если не вдаваться в https...Да кстати, какой-нибудь FAQ по https тоже не помешал бы.
 

Кром

Новичок
Developer
Вот этой строке не поможет никакой addslashes(). Это дыра, в защите, если ты еще на понял.
>$res = mysql_query("select * from users where name=$uname and pass=$upass");

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

Merk
>uid принимает значение 40 только в случае...
>Во всех остальных случаях это идентификатор из 30...

Это не правильно. Хранить в одной переменной то цену за баррель нефти, то количество строк в базе, то дату взятия Бастилии.
Подумая над логикой более тщательно.


>Кстати, я тут задумался. А кто может ткнуть носом в то, как зашифровать пароль ПЕРЕД отправкой формы?

Ссылку я тебе уже давал.
 

Фанат

oncle terrible
Команда форума
Merk
сформулируй внятно, что ты боишься, что перехватят и в какой момент.
Если еще не разобрался.
 

valyala

Новичок
Объясните мне, неопытному и деревянному, чем отличаются, к примеру, MD5, RC4, AES и RSA? Или эти аббривеатуры обозначают одно и то же?

Merk, тут тебе предлагают передавать хэши вместо паролей при авторизации. Этот метод заслуживает доверия и повсеместно используется. А теперь подумай, как передать пароль при регистрации пользователя. Хэширование тут не пройдет.
Ты сможешь подделать зашифрованный случайно сгенерированный uid из знаков так 30-ти?
Объясни, зачем шифровать случайный uid? Энтропия uid'а от этого не увеличится. А если еще будешь использовать хэширование вместо обратимого шифрования, то энтропия может уменьшиться из-за возможных коллизий хэш-функции.

p.s. Небольшой ликбез. Энтропия - это мера неопределенности. Широко используется в теории передачи информации и криптологии.
 

Кром

Новичок
>А теперь подумай, как передать пароль при регистрации пользователя. Хэширование тут не пройдет.

Почему это не подойдет при регистрации? Хеширование прекрасно подходит.
 
Сверху