Перейти к содержанию
Innovialabs

Как сделать безопасный сброс пароля и восстановление аккаунта

Практика4 мин

Коротко

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

Коротко

У безопасного сброса пароля пять свойств:

  • Непредсказуемый токен из криптографически стойкого генератора.
  • Короткий срок жизни и одноразовость: ссылка работает один раз и недолго.
  • Нет перечисления пользователей: ответ одинаковый, есть такой email или нет.
  • Лимиты на запрос ссылки и на попытки её использовать.
  • Уборка после сброса: остальные сессии и токены отзываются, пользователь получает уведомление.

Восстановление аккаунта — это альтернативный способ войти. Если он слабее основного входа, атакующий пойдёт именно через него.

Шаг 1: генерация и хранение токена

Берите минимум 32 случайных байта из стойкого источника — не timestamp, не ID пользователя и не Math.random(). В базе храните только хеш токена, чтобы утечка базы не превращалась в набор рабочих ссылок.

import crypto from "node:crypto";

const token = crypto.randomBytes(32).toString("base64url");
const tokenHash = crypto.createHash("sha256").update(token).digest("hex");
// сохраняем: user_id, token_hash, expires_at, used_at = null
// открытый токен уходит только в ссылке в письме

Обычного SHA-256 здесь достаточно: токен длинный и случайный. Медленные хеши нужны для паролей, которые придумывают люди.

Шаг 2: срок жизни и одноразовость

  • Ставьте короткий срок: минуты или час, а не дни.
  • Помечайте токен использованным атомарно, чтобы два параллельных запроса не прошли оба:
UPDATE password_resets
SET used_at = now()
WHERE token_hash = $1 AND used_at IS NULL AND expires_at > now()
RETURNING user_id;
  • При новом запросе сброса аннулируйте старые неиспользованные токены этого пользователя.
  • На странице сброса задайте Referrer-Policy: no-referrer, чтобы токен из URL не утёк в сторонние скрипты и аналитику.

Шаг 3: защита от перечисления пользователей

Форма «Забыли пароль» не должна показывать, какие email зарегистрированы:

  • Всегда одно сообщение: «Если аккаунт с этим адресом существует, мы отправили инструкции».
  • Время ответа должно быть похожим в обоих случаях — помогает отправка письма в фоновой задаче.
  • Проверьте, что форма регистрации и ошибки входа не выдают ту же информацию другим путём.

Шаг 4: лимиты

Ограничивайте по email/аккаунту и по IP:

  • запросы писем — чтобы никто не завалил почту пользователя и ваш почтовый бюджет;
  • попытки ввода токена или SMS-кода — чтобы короткий код нельзя было перебрать;
  • CAPTCHA или задержку включайте только при подозрительной активности, а не для всех.

Шаг 5: что происходит после сброса

  • Хешируйте новый пароль функцией для паролей (Argon2id, bcrypt или scrypt).
  • Завершите все сессии и refresh-токены, кроме, возможно, текущей. Если аккаунт был угнан, именно это выкидывает атакующего.
  • Отзовите оставшиеся токены сброса.
  • Отправьте уведомление: «Ваш пароль изменён. Если это были не вы, напишите в поддержку».
  • Не логиньте пользователя автоматически, если включена 2FA, — сначала второй фактор.

Email или SMS

КаналГлавные рискиЧто делать
Ссылка в emailВзломанная почта, пересланная ссылкаКороткий срок, одноразовость, уведомление о смене
SMS-кодSIM swap, переназначение номера, перехватСтрогие лимиты попыток; не делать SMS единственным фактором для ценных аккаунтов
ПоддержкаСоциальная инженерияПисьменный регламент проверки, никаких исключений «потому что срочно»

Смена email или телефона для восстановления — сама по себе чувствительное действие: требуйте текущий пароль или 2FA и уведомляйте старый адрес.

Восстановление и 2FA

Сброс пароля не должен отключать 2FA. Иначе доступ к почте даёт полный доступ к аккаунту. Обычная схема:

  • сброс меняет только пароль, вход по-прежнему требует второй фактор;
  • если второй фактор потерян — резервные коды, выданные при настройке 2FA;
  • без резервных кодов — медленная ручная процедура: проверка личности, период ожидания и уведомления на все известные контакты перед отключением 2FA.

Частые ошибки

  • Токены без срока жизни или многоразовые.
  • Токены в открытом виде рядом с записью пользователя.
  • Разные сообщения для «email не найден» и «письмо отправлено».
  • Старые сессии живут после смены пароля.
  • Секретные вопросы вроде «девичья фамилия матери» — ответы часто публичны или угадываются.

Частые вопросы

Безопаснее нет. После смены пароля попросите войти обычным способом или хотя бы запросите второй фактор, если 2FA включена.

Поможем с этим

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

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.