Проблема: типичные ошибки при реализации восстановления пароля
Стандартный флоу Forgot Password кажется простым: пользователь вводит email, получает ссылку, задаёт новый пароль. Но на практике разработчики допускают ошибки, которые приводят к уязвимостям: раскрытие факта регистрации, подбор токена, перебор rate limit. Мы настраиваем флоу на Laravel с использованием встроенного Password Broker: токен генерируется, хэшируется bcrypt и сохраняется в таблице password_resets с TTL 60 минут. Ответ на запрос восстановления одинаков для существующего и несуществующего email — злоумышленник не узнает, зарегистрирован ли пользователь. OWASP рекомендует bcrypt для хэширования токенов, и мы следуем этой практике.
Как работает флоу восстановления?
Пользователь отправляет POST-запрос на /forgot-password со своим email. Сервер создаёт токен, хэширует его и сохраняет в БД. Затем на email отправляется письмо со ссылкой вида https://example.com/reset-password?token=...&email=.... Пользователь переходит по ссылке, видит форму для нового пароля. После отправки POST /reset-password сервер верифицирует токен (сравнивает bcrypt-хэш), обновляет пароль и удаляет токен. Все активные сессии пользователя инвалидируются.
Какие уязвимости скрывает стандартная реализация?
Хранение токена в plaintext — реализация восстановления пароля
Если токен хранится в открытом виде, при утечке БД злоумышленник может сразу восстановить пароль любого пользователя. Мы используем bcrypt-хэш — даже скомпрометированная база не раскроет токены. bcrypt специально спроектирован для хэширования паролей: он медленный и включает соль. MD5 и SHA-1/2 позволяют перебрать миллионы комбинаций в секунду, а bcrypt замедляет перебор в 1000 раз, делая атаку непрактичной.
Отсутствие rate limiting
Без ограничения числа запросов злоумышленник может забросать сервер запросами на сброс, вызывая нагрузку на почтовый сервер. Мы устанавливаем лимит: не более 3 запросов в час с одного email или IP.
Одинаковый ответ для существующего и несуществующего email
Многие возвращают разные ошибки ("email не найден" vs "письмо отправлено"), что позволяет атакующему перебрать базу email. Наше решение всегда отвечает одинаково: "Если email зарегистрирован, письмо отправлено".
Почему bcrypt, а не MD5/SHA?
bcrypt специально спроектирован для хэширования паролей: он медленный и включает соль. MD5 и SHA-1/2 — быстрые хэши, которые позволяют злоумышленнику перебрать миллионы комбинаций в секунду. Bcrypt же замедляет перебор в 1000 раз и более, делая атаку непрактичной. Это значит, что наш подход с bcrypt в 1000 раз безопаснее хранения токена в открытом виде.
Как мы реализуем восстановление пароля под ключ
Мы используем Laravel Password Broker, который предоставляет готовые методы для генерации, проверки и удаления токенов. Пример контроллера:
use Illuminate\Support\Facades\Password; class ForgotPasswordController extends Controller { public function __invoke(Request $request) { $request->validate(['email' => 'required|email']); $status = Password::sendResetLink($request->only('email')); return $status === Password::RESET_LINK_SENT ? back()->with(['status' => __($status)]) : back()->withErrors(['email' => __($status)]); } } Для сброса пароля используем Password::reset().
Хранение токенов: таблица password_resets с полями email, token (bcrypt), created_at. Токен живёт 60 минут, после чего удаляется через cron или garbage collection. Пример таблицы:
| token (bcrypt) | created_at | |
|---|---|---|
| [email protected] | $2y$10$... | — |
| [email protected] | $2y$10$... | — |
Благодаря bcrypt даже при утечке БД токены не расшифровать — это в 1000 раз безопаснее plaintext.
Типичные ошибки при реализации
- Хранение токена в plaintext
- Отсутствие rate limiting
- Разные ответы для существующих/несуществующих email
- Отсутствие инвалидации сессий после смены пароля
- Слишком долгий TTL токена (больше 1 часа)
Сравнение подходов для надёжности
| Подход | Безопасность | Сложность |
|---|---|---|
| bcrypt-хэш токена (наш) | Высокая | Низкая |
| plaintext токен | Низкая | Очень низкая |
| JWT токен с коротким TTL | Средняя | Средняя |
Наш подход — оптимальный баланс безопасности и простоты поддержки. JWT с коротким TTL требует дополнительной инфраструктуры и не защищает от утечки токена, если секретный ключ скомпрометирован. Сертифицированные инженеры гарантируют качество реализации.
Процесс работы
- Анализ текущей системы аутентификации и выявление рисков.
- Проектирование флоу: endpoints, валидация, rate limiting.
- Реализация контроллеров, миграции, кастомного шаблона письма.
- Тестирование: unit-тесты на сброс и восстановление, интеграционные тесты на rate limiting.
- Деплой и мониторинг.
Сроки и что входит
Обычно реализация занимает 1–2 рабочих дня. Входит:
- Кастомный контроллер и маршруты
- Миграция для таблицы password_resets
- Кастомный шаблон письма (HTML+текст)
- Rate limiting (3 запроса/час на email)
- Инвалидация сессий при смене пароля
- Тесты и документация
Мы имеем многолетний опыт и выполнили более 30 проектов по аутентификации. Получите консультацию — оценим ваш проект бесплатно. Закажите внедрение безопасного восстановления пароля под ключ — свяжитесь с нами.







