2015-07-17 3 views
2

После прочтения о том, как обеспечить, чтобы токены «помнить меня» были защищены и читали исходный код библиотеки PHP-гейткипера psecio, я придумал следующую стратегию обеспечения безопасности, и я хотел узнайте, будет ли это ужасно неправильно. Я в основном делаю следующие вещи:Стратегия безопасного печенья

  1. Когда пользователь входит в систему, генерирует криптографически безопасную строку с использованием генератора случайных чисел системы. (random.SystemRandom() в Python) Это генерируется путем выбора случайных символов из выбора всех нижних и верхних букв и цифр ASCII. (''.join(_random_gen.choice(_random_chars) for i in range(length)), в соответствии с тем, как Django делает то же самое. _random_gen является защищенным генератором случайных чисел)
  2. Сгенерированный токен вставляется в базу данных RethinkDB вместе с идентификатором пользователя, с которым он идет, и время истечения 1 минуту в будущем. Затем создается значение cookie с использованием уникального идентификатора, который RethinkDB генерирует для идентификации этой записи и маркера хэширования sha256. По существу: ':'.join(unique_id, sha256_crypt.encrypt(token)). sha256_crypt из библиотеки passlib от Python.
  3. Когда пользователь обращается к странице, для которой требуется, чтобы они вошли в систему, фактическое значение cookie извлекается из базы данных с использованием сохраненного идентификатора. Затем хэшированный файл cookie проверяется против фактического файла cookie с использованием sha256_crypt.verify.
  4. Если проверка прошла, и ранее сохраненное значение времени меньше текущего времени, то предыдущая запись в базе данных удаляется и создается новая пара идентификаторов/токенов для хранения в виде файла cookie.

Это хорошая стратегия, или есть очевидный недостаток, который я не вижу?

EDIT: После повторного чтения некоторых сообщений переполнения стека, которые я связал в комментарии, я изменил процесс выше, чтобы база данных хранила хеш-маркер, а фактический токен отправляется обратно в виде файла cookie. (что будет происходить только по https, конечно)

+0

Почему шаг 2 (и половина из 3)? Если у вас есть случайный токен, этого достаточно.Это не станет более случайным или безопасным, хэшируя его произвольными способами. – deceze

+1

Я основываю это на разделе «Упреждающе надежная долгосрочная аутентификация» на странице https://paragonie.com/blog/2015/04/secure-authentication-php-with-long-term-persistence. См. Раздел «Проблема 2: Временные утечки» чуть выше его для контекста. И раздел «Часть II» http://stackoverflow.com/questions/549/the-definitive-guide-to-form-based-website-authentication – Freezerburn

ответ

0

Вы должны убедиться, что вы создали достаточное количество символов в вашей безопасной строке. Я бы нацелился на 64 бита энтропии, а это значит, что вам нужно не менее 11 символов в вашей строке, чтобы предотвратить любой тип практической грубой силы.

Это согласно OWASP's recommendation for Session Identifiers:

С очень большим вебом-сайтом, злоумышленник может попытаться 10000 догадок за секунд с 100,000 действительными идентификаторами сеансов, доступных для догадывался. Учитывая эти предположения, ожидаемое время для злоумышленника до успешно догадывается, что действительный идентификатор сеанса больше, чем 292 лет.

Учитывая, что 292 года, генерация нового в каждую минуту кажется немного чрезмерной. Возможно, вы можете изменить это, чтобы обновить его один раз в день.

Я также добавил бы систему соли соли к вашему хэшу, сохраненную ценность (известную как перец). Это предотвратит извлечение предварительно настроенных таблиц радуги из исходного значения сеанса, если злоумышленнику удастся получить доступ к вашей таблице сеансов. Создайте 16-битное криптографически безопасное случайное значение для использования в качестве перца.

Помимо этого, я не вижу врожденных проблем с тем, что вы описали. Обычно применяются обычные рекомендации: также используйте флаги HSTS, TLS/SSL и Secure cookie.

+0

Моя текущая настройка - генерировать 24 символа. И я добавлю перец в свой код, используя уже имевшуюся функцию, и просто сохраню это значение в модуле. Спасибо, что сообщили мне, что я на самом деле так рассуждаю! – Freezerburn

Смежные вопросы