Лучший способ реализации «забытого пароля»? [закрыто]

154

Я ищу лучший способ для реализации функции "забыл пароль".

Я выступаю с 2 идеями:

  1. Когда пользователь нажимает на забытый пароль, он должен ввести имя пользователя, адрес электронной почты и, возможно, дату рождения или фамилию. Затем письмо с временным паролем будет отправлено на адрес электронной почты пользователя. Пользователь использует временный пароль для входа и сбрасывает свой пароль.

  2. Аналогично, но электронное письмо будет содержать ссылку, позволяющую пользователю сбросить свой пароль.

Или кто-нибудь может предложить мне лучший и безопасный способ? Я также думаю отправить временный пароль или ссылку, заставить пользователя сбросить пароль в течение 24 часов, иначе временный пароль или ссылка не будут использоваться. Как это сделать?

Заки
источник
Я пометил пост, так как он выходит за рамки JSF - таким образом вы, вероятно, получите больше ответов.
Макдауэлл
6
@ Где бы ни была волна "давайте удалим этот закрытый вопрос, потому что XYZ" в мета в эти месяцы. Я просто хотел бы заявить, что этот конкретный вопрос не должен быть удален, если только не доказано, что решения имеют недостатки и что его существование буквально вредит больше, чем делу безопасности.
Феликс Ганьон-Гренье
1
OWASP «шпаргалка» для забытых паролей стратегии восстановления: owasp.org/index.php/...
daiscog
Ссылка, предложенная @megaflop, теперь печально сломана, вот новая ссылка: cheatsheetseries.owasp.org/cheatsheets/…
Марко Болис

Ответы:

187

Обновление: пересмотрено в мае 2013 года для лучшего подхода

  1. Пользователь вводит свое имя пользователя и нажимает кнопку «забыл пароль». Я также рекомендую ввести адрес электронной почты вместо имени пользователя, потому что имена пользователей иногда тоже забываются.
  2. Система имеет таблицу password_change_requestsс колоннами ID, Timeи UserID. Когда новый пользователь нажимает кнопку, в таблице создается запись. TimeСтолбец содержит время , когда пользователь нажал кнопку «Забыли пароль». Это IDстрока. Создается длинная случайная строка (скажем, GUID), а затем хэшируется как пароль (это отдельная тема сама по себе). Этот хеш затем используется как «ID» в таблице.
  3. Система отправляет пользователю электронное письмо со ссылкой на него. Ссылка также содержит исходную строку идентификатора (до хэширования). Ссылка будет выглядеть примерно так: http://www.mysite.com/forgotpassword.jsp?ID=01234567890ABCDEF. Страница Forgotpassword.jsp должна быть в состоянии получить параметр ID. Извините, я не знаю Java, поэтому не могу быть более конкретным.
  4. Когда пользователь нажимает ссылку в письме, он перемещается на вашу страницу. Страница извлекает IDиз URL-адреса, снова хэширует и проверяет таблицу. Если такая запись существует и ее возраст не превышает, например, 24 часа, пользователю будет предложено ввести новый пароль .
  5. Пользователь вводит новый пароль, нажимает ОК, и все живут долго и счастливо ... до следующего раза!
Vilx-
источник
1
наиболее подходящий способ реализовать это - отправить временный токен сброса пароля в виде электронного письма пользователю в виде простого текста (но никогда не сохранять его в виде простого текста в БД) - после того, как пользователь введет этот временный код, немедленно вынудите его повторно введите новый пароль. - для параноика, убедитесь, что на вашем SMTP-сервере есть ssl, чтобы ваши письма, содержащие конфиденциальную информацию, не отслеживались. в большинстве случаев такой подход довольно безопасен. если ваше дело требует дополнительной безопасности, у вас, вероятно, не должно быть пользователей, которые забывают свои пароли: S
Каушик Гопал,
6
Зачем генерировать случайную строку / guid, хешировать ее и использовать хеш? Не хватает ли гида?
Йерун К
15
@jeroenk - чтобы кто-то украл вашу БД, он не может подделать ссылку «Сбросить пароль» и изменить чей-либо пароль.
Vilx-
4
по сути, это описанный способ правильной переустановки пароля. crackstation.net/hashing-security.htm#faq
TruthOf42
1
@ Давид - О, я хотел редактировать пост, но тема заблокирована. :( Хорошо, давайте попробуем еще раз: ваша таблица будет содержать столбцы: ID, UserID, Time, TokenHash.. Вы сгенерирует две длинные, случайные строки Поместите первую строку ( «ID») в IDстолбце, хэш второго ( «маркер» ) и поместите хеш в TokenHashстолбец. Создайте ссылку как forogotPassword.jsp?id=asdasd&token=asdasd. Токен в ссылке НЕ хэширован. Имеет ли это смысл сейчас?
Vilx-
28

Все зависит от вашего сайта и уровня безопасности, которого вы пытаетесь достичь, но основной процесс для веб-приложения выглядит примерно так:

  1. Пользователь переходит на страницу «забыл мой пароль» и вводит свое имя пользователя или адрес электронной почты (в зависимости от того, что является уникальным), чтобы запросить сброс пароля.

  2. При желании на этом этапе вы можете подтвердить запрос, запросив дополнительную информацию, такую ​​как ответ на предварительно заданный секретный вопрос или дату их рождения и т. Д. Этот дополнительный уровень не дает пользователям получать электронные письма, которые они не запрашивали.

  3. Найдите учетную запись пользователя. Сохраните временный пароль (обычно GUID) и отметку времени для записи учетной записи. Отправьте пользователю электронное письмо с временным паролем.

  4. Пользователь либо щелкает ссылку, содержащую временный пароль и идентификатор пользователя в электронном письме, либо переходит на страницу «забыл мой пароль» и копирует и вставляет временный пароль и его идентификатор. Пользователь вводит свой новый пароль и подтверждает его.

  5. Найдите запись пользователя и, если текущее время находится в пределах указанного времени (например, 1 час) от отметки времени, сохраненной на шаге 2, то хешируйте и сохраните новый пароль. (Очевидно, только если временные пароли совпадают!). Удалите временный GUID и метку времени.

Принцип здесь заключается в том, что пользователю отправляется временный пароль по электронной почте, который позволяет ему изменить свой пароль. Первоначально сохраненный пароль (его следует хешировать!) Никогда не заменяется временным паролем, если пользователь его запомнил.

Исходный пароль никогда не будет отображаться пользователю, так как он должен быть хеширован и неизвестен.

Обратите внимание, что этот процесс полностью зависит от безопасности учетной записи электронной почты пользователя. Так что это зависит от уровня безопасности, которого вы хотите достичь. Обычно этого достаточно для большинства сайтов / приложений.

Дэвид Гленн
источник
24

Трой Хант делает несколько замечательных замечаний в своей статье « Все , что вы когда-либо хотели знать о создании функции безопасного сброса пароля» . Наиболее значимые выдержки:

[T] вот два общих подхода:

  1. Создайте новый пароль на сервере и отправьте его по электронной почте
  2. Отправить уникальный URL, который облегчит процесс сброса

Несмотря на множество указаний на обратное, первый момент - это не то, где мы хотим быть. Проблема заключается в том, что это означает, что постоянный пароль - пароль, к которому вы можете вернуться и использовать в любое время - теперь был отправлен по небезопасному каналу и находится в вашем почтовом ящике.

...

Но есть еще одна большая проблема с первым подходом в том, что он делает простую злонамеренную блокировку учетной записи. Если я знаю адрес электронной почты того, кто владеет учетной записью на веб-сайте, я могу заблокировать его в любое время, просто сбросив его пароль; это атака отказа в обслуживании на серебряном блюде! Вот почему сброс должен происходить только после успешной проверки права запрашивающего сделать это.

Когда мы говорим об URL сброса, мы говорим об адресе веб-сайта, который уникален для этого конкретного случая процесса сброса.

...

Мы хотим создать уникальный токен, который можно отправить по электронной почте как часть URL-адреса сброса, а затем сопоставить с записью на сервере вместе с учетной записью пользователя, таким образом подтверждая, что владелец учетной записи электронной почты действительно пытается сбросить пароль. Например, токен может быть «3ce7854015cd38c862cb9e14a1ae552b» и храниться в таблице вместе с идентификатором пользователя, выполняющего сброс, и временем, когда токен был сгенерирован (подробнее об этом чуть позже). Когда электронное письмо отправляется, оно содержит URL-адрес, такой как «Сброс /? Id = 3ce7854015cd38c862cb9e14a1ae552b», и когда пользователь загружает его, страница проверяет наличие токена и, следовательно, подтверждает личность пользователя и позволяет паролю быть изменен.

...

Другая вещь, которую мы хотим сделать с URL-адресом сброса, - ограничить токен по времени, чтобы процесс сброса был завершен в течение определенной продолжительности, скажем, в течение часа.

...

Наконец, мы хотим убедиться, что это одноразовый процесс. После завершения процесса сброса токен следует удалить, чтобы URL-адрес сброса больше не работал. Как и в предыдущем пункте, это означает, что у злоумышленника есть очень ограниченное окно, в котором он может использовать URL сброса. Кроме того, токен больше не требуется, если процесс сброса завершен успешно.

Он делает еще много хороших замечаний о том, как избежать утечек информации, CAPTCHA, двухфакторной аутентификации и, конечно же, основных рекомендаций, таких как хеширование паролей. Я думаю, что важно отметить, что я не согласен с Троем в отношении полезности вопросов безопасности, предпочитая скептицизм Брюса Шнайера в этой практике :

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

Дейв Липманн
источник
1
Эта ссылка содержит четкие изображения NSFW, есть ссылка, чтобы изменить это, но многие люди сначала сканируют страницу. Тупая идея!
nik0lai
Ссылка на статью Троя Ханта изменилась. Перейти к troyhunt.com/everything-you-ever-wanted-to-know
knarfancho
@knarfancho Исправлено, спасибо!
Дейв
15

Я пойду с:

  1. Спросите пользователя по электронной почте, проверьте, что электронная почта зарегистрирована
  2. Сгенерируйте GUID и отправьте его на этот адрес электронной почты.
  3. Не сбрасывайте пароль еще
  4. Пользователь нажимает на ссылку, а затем должен ввести новый проход
  5. Сбрасывайте пароль только после того, как пользователь зашел на ваш сайт и нажал кнопку сброса после ввода нового пропуска.
  6. Сделайте этот GUID истекающим в течение короткого периода времени, чтобы сделать его более безопасным.
andres.santana
источник
Я не хочу получать неприятности, спрашивая? но это связано с вашим ответом. Как вы генерируете GUID?
KingAndrew
2
-1 за то, что вы не внедрили какой-то хэш в ссылку, которую вы отправляете человеку
TruthOf42
11

Когда вы отправляете какую-либо информацию по электронной почте, она не будет защищена. Есть слишком много способов, чтобы кто-то мог получить это. Это была бы детская игра для опытного хакера, который хочет украсть вашу информацию.

Воздерживайтесь от отправки любой личной информации, такой как пароли и информация о доходах, по электронной почте, так как она может стать ОЧЕНЬ УДОВОЛЬСТВУЮЩЕЙ для вас и вашей организации в случае утечки или кражи такой информации. Серьезно подумайте о безопасности. Требуется только один инцидент, чтобы все кирпичи упали.

Что касается восстановления пароля, внимательно прочитайте Best Practices .

Суть в том, что приложение, следуя рекомендациям, должно позволить пользователю сбросить свой пароль. Личные вопросы безопасности должны быть использованы. Приложение не должно отправлять электронную почту, отображать пароли и устанавливать временные пароли.

РЕДАКТИРОВАТЬ: Обновленная ссылка

jinsungy
источник
Я попробовал ссылку для Забытых паролей Best Practices и получил 500 ошибок сервера. Как вы думаете, сервер сейчас не работает или есть другая ссылка?
KingAndrew
здесь вы идете .. fishnetsecurity.com/Resource_/PageResource/White_Papers/…
jinsungy
ссылка снова мертва
Эрик Коуп
7

Как уже говорилось, это зависит от требуемого уровня безопасности, однако, если вам нужен более высокий уровень, некоторые новые решения, которые я видел, включают в себя;

  • Отображение половины временного пароля после подтверждения личности пользователя (секретный вопрос, адрес электронной почты и т. Д.), А другая половина отправляется на учетную запись электронной почты. Если учетная запись электронной почты была взломана, маловероятно, что одному и тому же человеку также удалось выполнить атаку «человек посередине». (При посещении правительства Великобритании)

  • Подтверждение личности с помощью электронной почты и другого носителя - например, кода, отправленного с помощью текста на зарегистрированный мобильный телефон. (Видно на eBay / PayPal)

Поскольку где-то между этими двумя крайностями реализация вопросов безопасности может быть способом, упомянутым DaveG.

Том Вернер
источник
6

Если вы включите адрес электронной почты при регистрации. Кнопка «забыть пароль» отправляет электронное письмо на этот адрес электронной почты. Это гарантирует, что информация отправляется на доверенный адрес электронной почты.

(Если база данных не взломана, но тогда ничего не безопасно).

Тун Крижте
источник
5

Вот три очень хорошие ссылки, которые предоставляют информацию о сбросе пароля:

  1. http://jtauber.com/blog/2006/03/20/account_management_patterns/

  2. (Не позволяйте пользователям подтверждать с помощью GET): http://www.artima.com/forums/flat.jsp?forum=106&thread=152805&start=15&msRange=15

  3. http://fishbowl.pastiche.org/archives/docs/PasswordRecovery.pdf

Надеюсь, это поможет. Они наверняка помогли мне понять проблему.

KingAndrew
источник
4

Я бы применил уникальные адреса электронной почты для всех учетных записей.

Тогда это просто вопрос отправки ссылки на временную страницу, которая позволяет человеку изменить свой пароль. (разрешить 24 часа или меньше)

Учетная запись электронной почты пользователя является самой слабой ссылкой в ​​этом сценарии.

Эндрю Гарри
источник
2

Никогда не отправляйте пароль пользователю по электронной почте. Даже если он генерируется автоматически. Лучший подход (рекомендуется и используется SANS и другими):

  1. На странице забытого пароля спросите адрес электронной почты / пользователя и НОВЫЙ пароль от пользователя.
  2. Отправить ссылку на сохраненный адрес электронной почты для этой учетной записи со ссылкой для активации.
  3. Когда пользователь нажимает на эту ссылку, включите новый пароль.

Если он не нажимает на ссылку в течение 24 часов, отключите ее (чтобы она больше не меняла пароль).

Никогда не меняйте пароль без согласия пользователя. Это означает, что не отправляйте новый пароль по электронной почте только потому, что кто-то нажал на ссылку забытого пароля и выяснил имя учетной записи.

Sucuri
источник
13
Я занимаюсь этой техникой. Атакующий вводит вашу электронную почту и новый пароль. Владелец аккаунта получает письмо, что-то неправильно читает и нажимает на ссылку. Злоумышленник, находящийся в режиме ожидания и пробующий новый пароль каждую минуту, получает доступ к учетной записи, пока владелец учетной записи не поймет, что произошло, и в конечном итоге перейдет на страницу «забыли пароль».
Оди - Xceed
Еще одна проблема! предоставление нового пароля на время сброса пароля не является хорошим вариантом. Я могу забыть новый пароль еще раз, если проверил мою электронную почту в нерабочее время!
Язид Эрман