Как стать автором
Обновить

Комментарии 59

Весьма неплохо описаны существующие проблемы.

У нас в куках прописана самая насущная инфа + ключ сессии + подпись. Для работы с сессией написан класс-wrapper, который можно и на стандартные сессии переключить, и на memcached, когда понадобится. Количество данных в сессии в серьезных проектах обычно такое, что пихать все в куки не получится (еще ведь и оверхед передачи этих кук при каждом запросе браузера), да и с точки зрения безопасности не комильфо - есть куча вещей, которые я не хочу отдавать наружу в виде кук, пусть даже и как-нибудь зашифрованным.

Ну а для несложного проекта конечно такой подход сработает, но я бы все равно не рекомендовал. Если правильно спланировать архитектуру, то использовать данные из сессии нужно будет только в критичные моменты - например когда нужно проверить, может ли этот пользователь делать какое-то действие. То есть читать/писать сессии нужно будет далеко не для каждой открытой страницы.
А зачем подпись, если в куках ключ от сессии? Здесь-то подпись как раз для того, чтобы сами данные не модифицировались, а если данные не покидают сервер, то какой смысл подписывать ключ? Все равно его хрен угадаешь..
Подпись не для ключа, а для остальных данных (самая насущная инфа).
интересно
но почему-то кажется, что соотношение полезной информации к обьему всего текста тут очень невелико :(
хотя в закладки я все равно добавил
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Так а чем кидать куку "не прямо" ? Все ж кидают, это не я придумал :)
НЛО прилетело и опубликовало эту надпись здесь
Так зачем?! Зачем использовать сессии, если можно без них? Я нигде не говорю, что авторизацию сессиями сделать нельзя - можно! Конечно можно. И url_rewrite полезная вещь (обычно не для сессий, правда), и save_handler полезная вещь, но просто нужно ли это здесь? Зачем стрелять из пушки по воробьям, когда можно просто кинуть куку. :)
НЛО прилетело и опубликовало эту надпись здесь
У меня к тебе встречный вопрос: зачем использовать куки, когда есть сессии?;) Куки легче украсть и прочитать, а там может быть много интересного(пусть сразу ты эти данные применить не сможешь, но ты их будешь знать, что сильно поможет при дальнейшем взломе) + далеко не всегда хватает кук для данных(4Кб всетаки маловато бывает), поэтому используй Сессии на БД с защитой по IP, юзер агенту.
Вы путаете, что такое сессия, и путаете остальных. Сессия - это сеанс работы с пользователем. То что вы реализовали и есть сессия.
Причем ооочень редко применимая, т.к. при отрисовке большинства страниц требуется не только id пользователя, но и его имя, например, или флаг забанености. Еще один большой минус - ваша реализация сессий может хранить очень мало данных.
Я использую свой механизм сессий по одной простой причине это - корявая работа сессий на разных хостингах.
Может быть вопрос не в корявости работы сессий на разных хостингах, а в разнице дефолтных конфигов сессий на разных хостингах? И это не проблема, если при использовании сессий проставлять все значения в нужные нам. Даже те, которые совпадают с дефолтными.
Админь!
НЛО прилетело и опубликовало эту надпись здесь
Я в сессии храню исключительно такую информацию, которую пользователь ни при каких обстоятельствах не должен видеть. Куки же доступны всем и их можо смело править...
гы-гы а я храню то, что надо передавать в рамках сессии от вызова к вызову. (есть еще уйма мест для информации, которую не должен видеть пользователь) в куках только id.
хм а templer data зачем тогда? а используя баш и перл можно все что угодно сделать далше, что с сессией так и с куки
Круто, конечно, что можно использовать баш и перл, но я пишу на пхп ^^
$cookie = $userid . '|' . md5($userid . 'secret word' . $_SERVER['REMOTE_ADDR'] )

Да, с этим согласен. Ключевая строка в статье :)
Сессии в пхп — зло. Еще один повод лениться.
Привязывать к IP я бы не советовал, ибо тогда авторизация будет теряться в зависимости от положения пользователя (дома/на_работе/wi-fi_в_кафе). Соответственно нельзя привязывать и к железу.
Побольше бы таких статей, быть может часть кодеров наконец станут программерами.
Да и вообще, использовать сессии в php лишь для авторизации, все равно что из пушки по воробьям.
о чем вы? И чем сессии будут отличаться в перл, руби, питоне?
есть понятие сессий, глобальное. А есть реализация этого понятия под язык программирования php, опошленное и загрязненное кодерами этого языка. Я говорил именно о локальной реализации и использования сессий в php.
А еще есть пользователи dialup и gprs. Соединение оборвалось - IP поменялся - авторизация слетела.

Все-таки привязка к IP - единственная надежная (хотя не 100%) гарантия, что запрос пришел с той же машины.

Ведь $_SERVER['HTTP_USER_AGENT'] можно украсть теми же приемами session fixation, что и сам куки, а потом подделывать.
ОпСоС пользователям GPRS даёт внешний IP один на всех. Ну не на всех, на многих...
А какая связь сессии и авторизации?
Сессия, это конкретный сеанс работы пользователя с сайтом.
Зашел на сайт из кафе - одна сессия. Вышел, пришел домой, зашел снова с другого IP, это уже другая сессия.
Я смотрю ты вообще не врубаешься что такое сессия и для чего она нужна, при чем тут дома, на работе, ...?
Была бы карма, поставил бы плюсы gro и serega011 за правильные мысли и минус mobiz'у за неправильные.
не понимаю, зачем передавать в куки какую-либо информацию, кроме ключа — все равно ее выбирать из базы/проверять? Выборка из базы медленнее вычисления md5 ?
Выборка из базы медленнее вычисления md5 ?


$s = microtime(true);
md5('dfhuehfjdhjfhueyfuhjedhfjdfdfejhfuieyiufhjdhjfheuhfujdhjfd');
$e = microtime(true);
print ''.($e - $s);


0.0001218318939209

это в моем ноуте(и то в зенде, а не в консоли) - сможете найти запрос(полезый запрос), который сможет, хотябы примерно, отработать быстрее???
выборка из таблице по кластерному индексу — такая же материальная точка, что и вычисление md5 хеша. Теоретически, конечно, md5 хеш вычислится быстрее. Но вы никак не заметите это на практике.
вот нашел про кластерный - каюсь, не знал что такое, но судя по описнаию - данные в таблице уже должны быть отсортированны, но разве в мускуле это так? в MyISAM точно нет. а вот в InnoDB?
Индекс в реляционных БД, это основа основ.
ну это понятно, тока вот индекс-то не обязательно должен быть кластерный!
А сколько на вашем ноуте займет брутфорс полученного md5? :)
не практиковался
В данном примере используется md5 от REMOTE_ADDR и HTTP_USER_AGENT для защиты от подмены/кражи куки.
А эти параметры выбирать из базы не нужно, их можно получить из переменных окружения PHP :)
переменные сессии в фаловой системе - исправьте пожалуйста =)
Забудтье про браузеры и IP адреса. С браузером можно все что угодно сделать, это понятно. С IP адресом подскажу такую вещь, что AOL Explorer меняет его при каждой загрузке страницы.

Хотя для маленьких сайтов все подойдет - лишь бы "работало".
Как не заморачивайся с авторизацией, это спасёт лишь от так называемых script kiddies.

Если кто-то очень-очень-очень сильно захочет получить доступ к данным вашего сайта, он их получит.

Ибо в любой системе, какой бы она не была навороченной в плане защиты, самое слабое звено — человек.
добавлю сюда вот такую штучку из php.ini (многие её не знают)


session.save_path = "N;MODE;/path"

where:
N is an integer. Instead of storing all the session files in
/path, what this will do is use subdirectories N-levels deep, and
store the session data in those directories. This is useful if you
or your OS have problems with lots of files in one directory, and is
a more efficient layout for servers that handle lots of sessions.

MODE is the octal representation of the mode. Note that this
does not overwrite the process's umask.

правда появляются две проблемки

NOTE 1: PHP will not create this directory structure automatically.
You can use the script in the ext/session dir for that purpose.
NOTE 2: See the section on garbage collection below if you choose to
use subdirectories for session storage

но они очень легко решаются очень маленькими скриптиками

На возможность хранить файлы сессий в подкаталогах я тоже указывал в скрытом топике.
А вот про
session.save_path = "N;MODE;/path"
ничего в документации не встречал. Можете озвучить источник или ткнуть меня носом, если он в документации есть.
я ж и пишу - прямо из php.ini :) берем свеженький php.ini (а можно и не очень), находим строчку session.save_path и читаем коменты перед ней
Спасибо.
долгожданная статья:) взял себе некоторие моменти на заметку.
Автор вообще не вникал в тему, как мне кажется. Все написанное им можно реализовать настройками php.
Прочитал вот это:
"Встроенный в PHP механизм url_rewriter - необычайно мощная и полезная штука, но при использовании ее в сессиях возникает серия неприятных моментов. "Взбесившиеся" поисковики, некрасивые ссылки, заход под чужим именем, "засвет" своего sessid в логах совершенно посторонних сайтов (через HTTP_REFERER) и т.д. Посему обычно эту функцию отключают, и для передачи sessid используют исключительно куки."

И хотелось бы сказать автору вот что:
1. Стартовать сессию для поисковика вообще не надо. Надо стартовать сессию только когда это действительно необходимо. А потом уже стартовать как relation start. Что-то типа:
if ( isset( $_REQUEST[session_name()] ) )
{
$this->Start();
return true;
}

2. Если у пользователя включены куки, то механизм сессий будет использовать их. А вот если отключены - тогда только он "корявит ссылки"


В общем мне кажется вам надо бы еще подучиться. Вся работа с сессиями в php сводится к factory шаблону, который реализует просто обертку для стандартного механизма сессий. Если нужна реализация для memcached - то используется просто другая обертка. На этом вся работа с сессиями заканчивается
"Закорявит" в любом случае, но только если не знает, что у пользователя включены кукисы - т.е. при первом заходе на сайт и при первом переходе по внутренней ссылке.
Какой же бред несут некоторые комментаторы, не въезжают в тему. А по-моему же алгоритм вполне неплохой.
По подделке ID сессии: я использую функционал стандартных сессий PHP, но одна из переменных в ней - тот самый хеш, проверяющий IP адрес, userid и прочее. И соотвественно, при каждом вызове скрипта я это проверяю - если совпадает - продолжаем работу.
да но товарищи ж и пишут что IP и пользователя может меняться - причем иногда новый IP на каждый рефреш. как вариант - можно проверять подсеть, со всеми вытекающими...
блин интересно на хабр когда-нибудь добавят возможность редактировать свой коменты, втечении хотя бы 1 минуты после поста
Не забывайте про повторяемость мд5. Решений два:
1. использовать другой алгоритм хеширования
2. мд5'ить каждый компонент отдельно
например так:
$cookie = $userid . '|' . md5($userid . 'secret word') md5($_SERVER['REMOTE_ADDR'] . 'secret word');
это вы о чем вообще?
о том, что md5(a) с некоторой долей вероятности равно md5(b), соответственно md5($userid.'secret'.$_SERVER['REMOTE_ADDR']) с некоторой долей вероятности будет равно md5(something). А если таких конструкций будет две-три, то вероятность совпадения уменьшается кратно.
На практике это нереально. Использование ключей сессий md5 - проверенное, можно сказать промышленное решение.
НЛО прилетело и опубликовало эту надпись здесь
В 90% случаев вообще не нужно ломать голову над такими вопросами. Стандарные сессии отлично подойдут. Для мелких сайтов лучше, наоборот, НЕ использовать эти велосипеды.

Иногда требуется отслеживать пользователей на сайте (типа "сейчас на сайте 10 человек, рекорд был тогда-то" или "Сейчас на сайте Миша, Володя и Боря"). В этом случае, в таблице с фиксацией запросов от пользователей можно и сессионные данные хранить. А вызов метода, пишущего запись в таблицу, можно сделать и при помощи session_set_save_handler. Только вот лучше этого не делать. И вообще, по возможности, не увлекаться handler'ами, потому что это усложняет и запутывает код.

У пользователя в куках лучше всего хранить только ID сессии. Хранить этот же ID в таблице, + еще в ней же IP (и по желанию прочие привязки для секюрности), а при запросе брать запись из таблицы и сверять. А не шифровать у пользователя в куках.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории