Ответ 1
token_authenticatable
уязвим для временных атак, которые очень хорошо объясняются в этом сообщении в блоге. Эти атаки были причиной удаления token_authenticatable
из Devise 3.1. См. сообщение в блоге plataformatec для получения дополнительной информации.
Чтобы иметь самый безопасный механизм аутентификации маркера, токен:
-
Должно быть отправлено через HTTPS.
-
Должен быть случайным, с криптографической силой.
-
Необходимо безопасно сравнивать.
-
Нельзя хранить непосредственно в базе данных. Здесь может храниться только хэш-токен. (Помните, токен = пароль. Мы не храним пароли в обычном тексте в db, правильно?)
-
Срок действия истекает в соответствии с некоторой логикой.
Если вы откажетесь от некоторых из этих пунктов в пользу удобства использования, у вас будет механизм, который не настолько безопасен, как мог бы быть. Это так просто. Вы должны быть достаточно безопасными, если удовлетворяете первым трем требованиям и ограничиваете доступ к своей базе данных.
Расширение и объяснение моего ответа:
-
Использовать HTTPS. Это определенно самый важный момент, потому что он касается снифферов.
Если вы не используете HTTPS, то многое может пойти не так. Например:
-
Чтобы безопасно передавать учетные данные пользователя (имя пользователя/адрес электронной почты/пароль), вам придется использовать аутентификацию дайджеста, но который просто не режет эти дни, так как соленые хеши могут быть грубо вынуждены.
-
В Rails 3 куки только окутаны кодировкой Base64, поэтому их можно довольно легко выявить. Для получения дополнительной информации см. Decoding Rails Session Cookies.
Так как Rails 4, хранилище файлов cookie шифруется, поэтому данные как в цифровой форме, так и нечитабельно для злоумышленника. Файлы cookie должны быть защищены, если ваш
secret_key_base
не просочился.
-
-
Создайте свой токен, используя
SecureRandom.hex
. Или используйте драгоценный каменьsysrandom
.По-видимому,
SecureRandom
не является безопасным. Тем не менее, здесь есть компромисс: выберите что-нибудь из стандартной библиотеки или выберите немного известного драгоценного камня, которого кто-то поддерживает. Для обоснованного решения я предлагаю прочитатьsysrandom
README и сообщение в блоге Как создать безопасные случайные числа на разных языках программирования. -
Найдите запись пользователя, используя идентификатор пользователя, адрес электронной почты или другой атрибут. Затем сравните этот токен пользователя с токеном запроса с
Devise.secure_compare(user.auth_token, params[:auth_token]
. Если вы используете Rails 4.2.1+, вы также можете использоватьActiveSupport::SecurityUtils.secure_compare
.Do not найти запись пользователя с помощью Rails finder, например
User.find_by(auth_token: params[:auth_token])
. Это уязвимо для временных атак! -
Если у вас одновременно будет несколько приложений/сеансов для каждого пользователя, у вас есть два варианта:
-
Храните незашифрованный токен в базе данных, чтобы он мог использоваться совместно. Это плохая практика, но я думаю, вы можете сделать это во имя UX (и если вы доверяете своим сотрудникам доступ к БД).
-
Храните столько зашифрованных токенов для каждого пользователя, сколько вы хотите разрешить текущие сеансы. Поэтому, если вы хотите разрешить 2 сеанса на двух разных устройствах, сохраните 2 разных хэша токена в базе данных. Этот вариант немного менее прост в реализации, но он определенно безопаснее. У этого также есть потенциал, позволяющий предоставить вашим пользователям возможность прекратить текущие активные сеансы на определенных устройствах, отменив их токены (так же как GitHub и Facebook).
-
-
Должен существовать какой-то механизм, который заставляет токен истекать. При внедрении этого механизма учитывайте компромисс между UX и безопасностью.
Google заканчивает токен, если он не использовался в течение шести месяцев.
Facebook истекает токен, если он не использовался в течение двух месяцев:
Родные мобильные приложения, использующие SDK для Facebook, получат долговременный доступ токены, хорошие около 60 дней. Эти токены будут обновляться один раз в день, когда пользователь, использующий ваше приложение, обращается с просьбой к Facebook сервера. Если запросы не будут выполнены, токен истечет после примерно 60 дней, и человеку придется снова пройти поток входа в систему получите новый токен.
-
Перейдите к Rails 4, чтобы использовать его зашифрованное хранилище cookie. Если вы не можете, тогда зашифруйте хранилище файлов cookie самостоятельно, как предлагается здесь. Не было бы проблем с хранением токена аутентификации в зашифрованном хранилище cookie.
У вас также должен быть план на случай непредвиденных обстоятельств, например, задача rake для reset подмножества токенов или каждого отдельного токена в базе данных.
Чтобы начать работу, вы можете проверить этот смысл (одним из авторов Devise) о том, как реализовать аутентификацию токена с помощью Devise, Наконец, Railscast для защиты API должен быть полезен.