Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737 Форумы портала PHP.SU :: Нужно ли сверять токен в БД?
Покинул форум
Сообщений всего: 298
Дата рег-ции: Нояб. 2009
Помог: 14 раз(а)
Приветствую, господа! У меня есть пара маленьких вопросов в плане безопасности, а точнее её усилении. После успешной аутентификации, пользователю в сессию записывается токен, который подставляется во все формы и сверяется на сервере. Есть ли смысл записывать токен в БД и при каждом запросе сверять его еще и там? Вот сижу и думаю: если на одну чашу весов положить такую дополнительную меру, а на другую - мучит БД при каждом запросе, то сто́ит ли игра свеч? Да и вообще, имеет ли смысл использовать токен после успешной авторизации, если работа ведется по SSL? Может быть достаточно просто проверять: есть сессия или нет?
Viper
Отправлено: 06 Ноября, 2015 - 09:40:11
Активный участник
Покинул форум
Сообщений всего: 4555
Дата рег-ции: Февр. 2007 Откуда: Симферополь
Помог: 98 раз(а)
Если объект сессии хранится в БД то не имеет смысла дергать каждый раз, если иначе то обязательно.
Deonis пишет:
имеет ли смысл использовать токен после успешной авторизации, если работа ведется по SSL?
Покинул форум
Сообщений всего: 298
Дата рег-ции: Нояб. 2009
Помог: 14 раз(а)
Viper пишет:
А какая разница?
Я просто пытаюсь разобраться. Организация безопасности - это моё самое слабое место, т.к. я к этому практически не имел отношения (до сегодняшнего дня). Мне досталась "в наследство" CRM, с которой я пытаюсь разобраться и, по возможности, оптимизировать её. На данный момент было организовано так:
1. Если пользователь не аутентифицирован, то генерируется случайный хеш, который используется, как токен в форме логина.
2. После успешной авторизации, этот хеш записывается в БД и в сессию.
3. При любом запросе, хеш из сессии сверяется с хешем в БД. Если гуд, то пользователь авторизован и работа продолжается, если нет, то выбрасывается на страницу логина.
4. Кроме того, этот хеш используется в формах в скрытых полях. Как я понимаю - это для защиты от CSRF.
Вот я и пытаюсь разобраться: нет ли тут чего лишнего и сделано ли по уму, может можно что-то упростить, а может надо кардинально что-то поменять, если допущены грубые ошибки.
Viper
Отправлено: 06 Ноября, 2015 - 10:51:12
Активный участник
Покинул форум
Сообщений всего: 4555
Дата рег-ции: Февр. 2007 Откуда: Симферополь
Помог: 98 раз(а)
Deonis пишет:
При любом запросе, хеш из сессии сверяется с хешем в БД.
вот эту говняху лучше сократить до чего-то одного. Т.е. сессия в БД, с ней и работаем, незачем ещё писать в файл.
Deonis пишет:
Кроме того, этот хеш используется в формах в скрытых полях. Как я понимаю - это для защиты от CSRF.
Покинул форум
Сообщений всего: 298
Дата рег-ции: Нояб. 2009
Помог: 14 раз(а)
DeepVarvar пишет:
Краткий список задач по пунктам тебя устроит?
Устроит.
P.S. Впрочем, забудьте. А то у меня создается ощущение, что я клянчу.
DeepVarvar пишет:
И как это тебя оправдывает?
Я не ищу оправданий, т.к. они мне не нужны. Я объяснял ситуацию и не более того.
DeepVarvar пишет:
Работа то -- твоя.
Естественно! Поэтому я и не просил, чтоб кто-то делал её за меня. Вы видели где-то в моем вопросе что-то вроде кода, с просьбой поправить его? Вопрос риторический. А если вы считаете, что делиться личным опытом или указывать на какие-то конкретные ошибки с конструктивным пояснением - это приравнивается к "сделайте за меня", то пардоньте, что потревожил.
Покинул форум
Сообщений всего: 1462
Дата рег-ции: Апр. 2013
Помог: 91 раз(а)
Deonis пишет:
Есть ли смысл записывать токен в БД и при каждом запросе сверять его еще и там?
Нет. В двойной сверке с данными, которые хранятся на сервере, нет необходимости.
Deonis пишет:
Да и вообще, имеет ли смысл использовать токен после успешной авторизации, если работа ведется по SSL?
Задача - обезопасить себя от CSRF атак, поэтому нужно задействовать более подходящий для задачи механизм, то есть токены. Желательно одноразовые.
Deonis пишет:
Может быть достаточно просто проверять: есть сессия или нет?
Если речь о CSRF, то не достаточно. Нужно обязательно сверять токен отправленный клиентом и тот, что хранится на сервере. Ну а если токен от клиента не пришел, то такой запрос можно считать не валидным.
Deonis пишет:
$_SESSION['login'] === true;
Так это, вроде бы, не надёжно.
Лучше проверить например на isset, потому что данного ключа может просто не существовать.
Если нужно проверить на наличие ключа + сверить значение этого ключа, то действуем соответственно.
Deonis
Отправлено: 07 Ноября, 2015 - 02:00:49
Посетитель
Покинул форум
Сообщений всего: 298
Дата рег-ции: Нояб. 2009
Помог: 14 раз(а)
teddy пишет:
В двойной сверке с данными, которые хранятся на сервере, нет необходимости.
обезопасить себя от CSRF атак.... токены. Желательно одноразовые.
Спасибо, понял.
teddy пишет:
Deonis пишет:
$_SESSION['login'] === true;
Так это, вроде бы, не надёжно.
Лучше проверить например на isset, потому что данного ключа может просто не существовать.
Тут я засомневался немного в другом ключе, в плане идентификации пользователя, который работает в данной сессии. Наверно, это уже относится к XSS, но если украсть сессию, то обычное булевое значение, указывающее на то, что юзер залогинен, даст полный доступ ко всем его данным. Хотя, это рассуждения с дилетантской точки зрения.
Но в целом, спасибо за советы.
DeepVarvar
Отправлено: 07 Ноября, 2015 - 03:24:36
Активный участник
Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008 Откуда: Альфа Центавра
Помог: 353 раз(а)
teddy пишет:
проверить например на isset, потому что данного ключа может просто не существовать
Не надо нам тут гвозди забивать двуручной пилой.
Deonis пишет:
Устроит
1) Перенести хранение сессии в БД, полностью и чтоб она только там была.
2) Стартовать сессию (ага, к БД не забудь подключиться) всегда, вне зависимости от того кто это, гость или пользак.
И если гость -- формировать идентичный профилю пользака объект, с пометкой что это гостевая роль.
3) Перевести все, требующие защиты от CSRF места, на POST/PUT/DELETE запросы.
После чего не использовать CSRF-токен вообще.
Только учти что эти три пункта легко могут обеспечить тебя гемором на пол года вперед.
Поэтому определись:
а) готов ли ты к долгоделу?
б) готов ли ты велосипедить?
в) может лучше взять серьезный фреймворк? там все это есть
г) может оставить все как есть?
Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009 Откуда: Россия, Санкт-Петербург
Помог: 618 раз(а)
DeepVarvar пишет:
Перевести все, требующие защиты от CSRF места, на POST/PUT/DELETE запросы.
После чего не использовать CSRF-токен вообще.
Так, видимо, эту тему всё-таки надо прочитать и понаписать текста. (Добавление)
Deonis пишет:
пользователю в сессию записывается токен, который подставляется во все формы и сверяется на сервере. Есть ли смысл записывать токен в БД и при каждом запросе сверять его еще и там?
Давайте начнём с проверки понимания: зачем этот токен делается? Без него же проще.
Идея ответа верна - защита от CSRF. Но зачем он делается?
Отдельный вопрос DeepVarvar'у: если на подконтрольную тебе страницу пришёл пользователь, какая тебе проблема попросить браузер пользователя сделать не GET-запрос на атакуемую страницу, а тот же POST?
Собственно идея: GET должен только читать данные. Обработка GET не должна менять состояние мира. Если это выполняется - то GET-запросы от CSRF защиты не требуют.
А вот запросы на изменение данных - требуют.
Возвращаясь к сути CSRF. Вектор атаки в том, что пользователь авторизован у вас, но свободно гуляет по интернету с этого же браузера. Случайно попадает на совершенно посторонний сайт (злоумышленника или хороший сайт, но скомпрометированный), на котором размещён код, который заставляет браузер пользователя выполнить запрос на ваш сервер. Браузер послушно лезет на ваш сервер, любезно подставляет авторизационные куки, и ваш сайт, считая что пользователь зашёл сам, выполняет этот запрос. Готово, пользователь того не хотел и обычно даже не заметил, а что-то нехорошее произошло.
Ну и нафига тут БД?
К слову про SSL - в вопросе CSRF ничем не отличается от HTTP. Даже не требует атакующему быть HTTPS - запрос из HTTP на HTTPS считается безопасным и не даёт предупреждений пользователю, в отличии от обратного.
Deonis пишет:
Так это, вроде бы, не надёжно.
Надёжно. Если перехватят куку - то дублирование токена в базе ничего не заметит. А других методов подменить файл сессии нет. Ну кроме прямого доступа к серверу.
Таким образом вы лишь мешаете авторизоваться с двух машин. Например, со смартфона и десктопа одного и того же человека.
Deonis пишет:
но если украсть сессию
То чуть менее чем весь мир у ваших ног. Потому что куки - единственный метод отличить одного пользователя от другого, предоставляемый нам протоколом HTTP.
И HTTPS этой угрозе хорошо мешает. Только вот там тоже не всё так просто. SSL уязвим и использовать его уже нельзя (любой версии). Использовать надо TLS и ещё сколько-то гаек покрутить в области допустимых ciphers
Если параноить, то можно поверх немного прикрутить. Например, поведенческие факторы: если пользователь час назад заходил из Москвы, и тут вдруг из Китая - возможно, что-то не так. Но это мог быть просто VPN. Если вы не банк и у вас нет чемодана денег на разработку - то сессионной куки достаточно.
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.