ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 28.04.2024
Просмотров: 97
Скачиваний: 0
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
При разработке кода всегда по умолчанию указывайте true для параметра httponly, и отключайте этот параметр только тогда, когда его действительно нужно использовать в JavaScript.
-
Советы по хранению паролей
Никогда не храните пароли в открытом виде ни в базе данных, ни на локальном компьютере пользователя (в виде файлов cookies). О том, что хранение паролей на локальном компьютере пользователя небезопасно, должен знать каждый. Чуть позже мы рассмотрим один из распространенных способов воровства пользовательских данных — XSS уже на практике, но не стоит забывать и про классику в виде троянских программ или просто уязвимости в браузере пользователя, что встречается сейчас не часто, но теоретически может произойти.
Хранение паролей на web-сервере в открытом виде также не безопасно. Если хакер найдет уязвимость, позволяющую реализовать SQL-инъекцию, то он сможет получить из таблиц ваш пароль и незаметно пользоваться правами администратора. Если пароль хранится в зашифрованном виде, то подобрать его можно только перебором. Да, хакер может внести новую запись в базу данных и дать ей права администратора (установить определенный признак), но это будет слишком бросаться в глаза, и администратор быстро увидит, что произошел взлом.
В случае хранения паролей в зашифрованном виде аутентификация происходит достаточно просто. Получив имя пользователя и пароль, шифруем пароль и сравниваем с уже зашифрованным вариантом из базы данных. Если шифры совпадают, то аутентификация прошла успешно.
А как же реализовать возможность восстановления пароля, если в открытом виде он не сохраняется в базе данных? А никак. Все сайты, которые заботятся о своих пользователях и их безопасности, не позволяют увидеть старый пароль, а разрешают только сменить его на новый.
По запросу на восстановление пароля необходимо:
-
запросить адрес электронной почты пользователя; -
найти запись в базе данных, соответствующую данному адресу; -
сгенерировать случайный код, который отправляется пользователю на почту;
♦ пользователь после этого вводит код на странице восстановления пароля и ему дается разрешение на смену.
Можно генерировать пароль на стороне сервера и давать его пользователю. Это действительно может быть безопасно, потому что мы будем уверены, что сгенерирован действительно сложный пароль. Но в этом случае нужно быть аккуратным. Злоумышленник может пошутить над другом и вызвать восстановление пароля для него только для того, чтобы система сгенерировала новый пароль.
Никогда не реализуйте возможность автоматического входа в панель администрирования. Это даже нарушает некоторые стандарты безопасности.
-
Соль на рану
Если вы храните в базе данных пароли только в зашифрованном виде и восстановление возможно только подбором пароля, то это еще не значит, что систему можно считать защищенной. Да, подбирать пароль очень долгое занятие, но не обязательное. Дело в том, что можно заранее рассчитать все возможные комбинации хеширования и занести их в большую базу данных. Да, база данных получится не очень маленькой, но для современного компьютера это капля в море. Зато любой пароль можно будет взломать за мгновение. Если отсортировать базу данных, то поиск нужного значения сведется к одной лишь операции — получить пароль, соответствующий хешу, без какого-либо шифрования.
Самое страшное, что создав одну лишь базу данных, можно будет подбирать к хеш- значениям пароли на любых сайтах и в любых системах. Неужели нет выхода? Выход есть, и он, как всегда, прост. Перед тем как получить хеш для пароля, просто прибавляем к нему какую-то строку:
В данном случае строка dfge4sdf является мусором (его часто называют солью), который просто усложняет пароль. Теперь, если хакер воспользуется своей базой данных для поиска пароля по хешу, то он получит строку, которая содержит не только пароль, но и мусор. Не зная, что является мусором, хакер не сможет определить, где же тут действительно пароль.
А что если пользователь выбрал очень простой пароль? В этом случае его легко можно будет увидеть. Но даже если пароль сложный типа dfgj k435, то после поиска по своей таблице хакер получит пароль: dfgjk435dfge4sdf. Да, это неверное значение, но найти, что тут является паролем, можно банальным перебором.
А давайте посмотрим на следующий вариант соления:
$crypted = md5(md5($pass).md5($salt));?>
Тут хешируется результат сложения двух хешей — пароля и соли. Вот такой вариант соления становится намного сложнее для подбора по словарю, особенно если хакер не знает, что выступает в качестве переменной $salt. Я не специалист в шифровании, но если не ошибаюсь, то, даже зная значение соли, хакеру придется рассчитывать значения новой базы данных для этой соли, а это очень утомительное и затратное для процессора занятие. Это идентично полному перебору паролей.
Фиксированная соль потребует от хакера генерации уникальной базы данных всех возможных вариаций паролей, но если сильно постараться, то он может это сделать, просто нужно рассчитать md5 для всех возможных вариаций a + salt, b + salt, c + salt и т. д.
Чтобы этот подход сделать бесполезным, можно делать соль уникальной для каждого пользователя и хранить ее в базе данных. Когда я работал над чувствительными к безопасности данными, то у меня в базе пользователей было две колонки: пароль и соль. Соль генерировалась случайным образом и была уникальной для каждого пользователя, потому что это был GUID.
Когда пользователь вводил свой пароль для авторизации, допустим user@gmail.com и пароль pass1234, то система искала в базе пользователя с таким e-mail, допустим, это была запись со значениями:
Email: user@gmail.com
Salt: e776633c-3eaa-4b7f-805c-aa046cd9eaee Password: B1286032C45E3D422F1B1214D4006E0C
Теперь я брал соль и объединял ее с введенным паролем — получался код:
e776633c-3eaa-4b7f-805c-aa046cd9eaeepass1234
Теперь рассчитывался Hash, для примера можно взять md5, и в результате получалось B1286032C45E3D422F1B1214D4006E0C, что соответствует сохраненному паролю.
Да, в базе данных приходилось хранить для каждого пользователя отдельную уникальную соль, но это делает подбор по словарю невозможным и бессмысленным. Генерировать таблицы смысла нет, у каждого пользователя соль своя.
Я здесь привожу в качестве примера хеширования md5, как самое простое решение, которое поддерживают все, но он все же уже не рекомендуется к использованию, потому что его перебор не такой уж и сложный. Соль позволяет добиться какой-то защищенности, но для современных компьютеров MD5 уже не является проблемой. Сейчас рекомендуется использовать SHA-2, как более защищенное хеш-решение.
-
Фиксация сеанса или сессии
Еще одна интересная атака на авторизацию — когда хакер не ворует существующую сессию, а подсовывает пользователю свою.
В разд. 9.2 мы рассматривали авторизацию, когда в cookie сохранялся идентификатор сессии. Тогда задача хакера была украсть ID-сессии.
Некоторые фреймворки позволяют передавать ID-сессии через URL, или хакер может интегрировать на сайт JavaScript-код, который будет добавлять cookie-значение со своим идентификатором сессии.
Рассмотрим первый вариант, когда идентификатор передается через URL. Хакер может передать идентификатор прямо в строке URL, отправив такую ссылку пользователю, аккаунт которого нужно взломать:
http://website/?SID=abc12345def
Здесь abcl2345def — это идентификатор сессии. Когда пользователь кликнет по адресу и загрузит сайт, то сайт может установить в качестве идентификатора сессии именно этот идентификатор, и это может стать проблемой. Пользователь заходит на сайт, и теперь сессия abcl2345def становится авторизованной, и хакер может использовать этот же идентификатор.
Если в разд. 9.2 задача хакера была украсть идентификатор сессии, то тут это не нужно, он его уже знает, ведь именно хакер подсунул свой код.
Если попытаться запретить создание идентификаторов сессии через URL, то это не спасет и не решит полностью проблему. Допустим, что пользователю можно назначать только ID существующей сессии и нельзя указывать что-то свое, о чем сервер не знает и не подозревает. Отлично, но хакер может загрузить один раз сайт и получить идентификатор сессии и использовать уже его.
Сайт не должен принимать идентификаторы сессий через URL, и для простых сайтов это возможно, а вот для WebAPI, который использует REST, это может не работать. Тут очень часто используется не cookie, а именно параметры get или post.
По возможности нужно отказаться от передачи идентификатора сессии через параметры, особенно через URL, и это необходимая, но не достаточная защита.
Допустим, что сайт будет проверять и игнорировать любые идентификаторы и не позволит использовать идентификатор сессии из URL вовсе. Но если на сайте есть XSS-уязвимость (о чем мы будем говорить в главе 10), то с помощью cookie с нужными значениями можно попытаться создать защиту с помощью JavaScript. С помощью обращения к document.cookie можно создавать, менять и удалять cookie.
Например, следующий код создает новый cookie с именем sid: document.cookie = "sid=abc12345def ";
Если на сайте нет XSS-уязвимости, то теоретически можно пытаться делать обходные защиты, но если говорить о хорошей защите, то самая простая из них - перезапускать сессию после входа на сайт.
Когда пользователь авторизуется на сайте, то текущий идентификатор сессии должен всегда уничтожаться, создаваться новый, и именно новый должен быть авторизован. Даже если хакер подкинет идентификатор сессии, пользователь не сможет превратить его в авторизованный.
Проблема фиксации сессии иногда встречается с использованием разных подходов к авторизованным и неавторизованным пользователям. Например, мне приходилось сталкиваться с сайтами, где неавторизованные пользователи работали с HTTP- версией сайта без шифрования. Как только пользователь авторизуется, то сразу же его переводят на HTTPS-версию сайта.
Но если идентификатор сессии один и тот же, то есть вероятность, что хакер перехватит незашифрованный трафик и получит доступ к идентификатору сессии. Если после входа на сайт тот же идентификатор будет передаваться по HTTPS, это пользователя уже не спасет, потому что идентификатор все же тот же.
-
Закрытые сессии
Когда пользователь говорит, что он хочет покинуть сайт, то на сервере для данного пользователя просто убивают cookie, которая отвечает за сессию. Пользователь теряет связь со своей сессией, ему создается новая, которая будет неавторизована.
Это достаточно простое и вполне рабочее решение с точки зрения реализации, но если сессия на сервере, идентификатор сессии все еще существует, то пользователь может вручную установить этот идентификатор себе в cookie и восстановить ее. Пользователь этого делать не будет, но вот хакер может.
Так что создавая видимость того, что сессия пользователя завершилась, мы обманываем пользователя, а хакер все еще сможет ее использовать.
Если вы уничтожаете cookie, то убедитесь, что и сама сессия удаляется или помечается как некорректная.
-
Сессии публичных сайтов
Как мы уже отмечали, сессии должны быть короткими и должны устаревать — именно так делают банки. То же самое часто делают и публичные сайты, просто мы это не замечаем.
Например, когда пользователь заходит на сайт Super Network, создается две сессии, и обе привязываются к одному и тому же аккаунту. Первая сессия долгосрочная и может быть активной в течение недели или даже месяца. Она дает пользователю право просматривать какую-то информацию или даже выполнять какие-то действия, но как только пользователь пытается выполнить чувствительное к персональным данным действие, то для этого проверяется вторая краткосрочная сессия. Если она устарела, то пользователя просят ввести пароль.
Таким образом с помощью двух сессий мы можем контролировать, что сейчас разрешено.
В случае с социальными сетями такое не пройдет, тут достаточно много действий, которые чувствительны к персональной информации. Что защищать короткой сессией? Публикацию новых записей нельзя, потому много блогеров публикуют новые записи регулярно. Запретить добавление в друзья тоже нельзя, некоторые это делают регулярно.
В таких случаях единственное, что остается делать для защиты пользователей, — защищать аккаунт от смены имени и пароля и какой-то информации, которая относится к аккаунту. Если хакер каким-то магическим образом захватил сессию, то он сможет публиковать новые записи на стене, сможет добавлять других людей в друзья, но мы должны сделать все, чтобы он не смог поменять e-mail и пароль.