Нормальный поток для того, чтобы изменить пароль пользователя почтой является этим:
Однако поддержание таблицы и истечение старых строк и т.д. походят на что-то вроде ненужной стычки. Есть ли в этом альтернативном подходе какие-либо очевидные дефекты?
Обратите внимание, что пароль пользователя уже хранится в хешированной и соленой форме, и я просто хеширую его еще раз для получения уникальной, но повторяемой строки.
И да, существует один очевидный "дефект": ссылка сброса, таким образом сгенерированная, не истечет, пока пользователь не изменится, их пароль (нажимает на ссылку). Я действительно не вижу, почему это было бы проблемой, хотя - если почтовый ящик поставлен под угрозу, пользователь завинчен так или иначе. И нет никакого риска повторного использования, с тех пор после того как пароль пользователя изменяется, ссылка сброса больше не будет соответствовать.
Чтобы исправить очевидный недостаток
, добавьте текущую дату (и дополнительную информацию о времени, представляющую текущую долю дня, если даже day слишком длинный) к тому, что вы хешируете, чтобы сгенерировать загадочную строку и проверить ее - это приводит к тому, что строка «истекает» (вы можете проверить предыдущую, а также текущую дату или дробную часть, если вы хотите более длительное «истечение»). Так что мне кажется, что ваша схема вполне жизнеспособна.
Если бы кто-то получил доступ к вашей базе данных с помощью хэшей паролей, они не узнали бы настоящих паролей. Если вы реализуете эту систему, они могут сами генерировать ссылки для сброса и сбрасывать пароли. Имея случайные строки и зная о компрометации, вы можете сделать недействительными все случайные строки, и только пользователи в процессе сброса пароля будут скомпрометированы, даже не зная о доступе. Маловероятный сценарий, но, возможно, стоит рассмотреть его, учитывая номинальные накладные расходы на случайные строки.
На самом деле, подумав об этом еще раз, ваш метод потенциально менее безопасен, чем "Обычный поток".
Если вы просто отправите обратно HASH(HASH(оригинальный пароль пользователя))
, я вижу сценарии, в которых это может дать злоумышленнику рычаги влияния:
Сценарий 1:
Jim
регистрируется на вашем сайте как jimjones@microsoft.com
. Джим
запрашивает сброс пароля, но не использует его. Письмо со сброшенным паролем навечно остается в его почтовом ящике. Джим
меняет свой адрес электронной почты на вашем сайте. jimjones@gmicrosoft.com
взломан Bob
. Боб
теперь проводит атаку перебором через свою распределенную ферму GPGPU и восстанавливает пароль Джима
. Сценарий 2:
Джим
использует пароль jimjonesupinthisma!
для своего банковского счета. Jim
регистрируется на вашем сайте как jimjones@microsoft.com
. jimjones@microsoft.com
никак не связан с банковским счетом Джима
. jimjones@gmicrosoft.com
взломан Бобом
. Боб
запрашивает сброс, теперь у него есть HASH(HASH(пароль Джима))
. Боб
теперь проводит атаку перебором через свою распределенную ферму GPGPU и восстанавливает пароль Джима
, который он затем использует для доступа к банковскому счету Джима
. Сценарий 3:
(Ваш сайт использует TLS, пользователи регистрируются через TLS.)
Джим
регистрируется на вашем сайте как jimjones@microsoft.com
. Боб
запрашивает сброс пароля на учетной записи Джима
. Боб
работает в АНБ в комнате 641A. Боб
использует свой глобальный интернет-снифер и получает HASH(HASH(пароль Джима))
, поскольку он отправлен по электронной почте открытым текстом на jimjones@microsoft.com
. Боб
теперь проводит атаку перебором через свою распределенную ферму GPGPU и восстанавливает пароль Джима
. Варианты сценариев 1 и 2 происходят постоянно (в зависимости от того, насколько сильны хэш и пароль), я не уверен насчет 3. Дело в том, что ваш метод пропускает ненужную информацию, которая действительно может использовать злоумышленника против вашего пользователя.
Я предлагаю использовать случайно сгенерированные токены, которые не имеют ничего общего с паролем пользователя.