Как взломали LinkedIn через предсказуемые токены восстановления паролей и почему это может случиться снова

Взлом LinkedIn через предсказуемые токены
Взлом LinkedIn через предсказуемые токены

В 2012 году произошла история, которую многие помнят только через заголовок «утекли пароли LinkedIn». Но менее известная часть — токены восстановления пароля были предсказуемыми, и это позволяло злоумышленникам не только сбрасывать чужие пароли, но и массово брать контроль над аккаунтами.

Это не «хак суперкомпьютером». Это ошибка в том, что казалось мелочью.

Что такое токен восстановления?

Когда пользователь нажимает «Забыли пароль?», система создаёт одноразовый токен, отправляет его по email/хешом в ссылке и затем проверяет его при переходе.

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

У LinkedIn на тот момент это выглядело примерно так (упрощённо):

https://linkedin.com/reset?user=12345&token=ab45cd67

То есть проблема была не в форме, а в содержании.

Что сделали неправильно?

Токены имели структуру, которую можно было угадывать, потому что они:

  • генерировались частично на основе timestamp
  • использовали предсказуемый PRNG
  • имели ограниченную длину (мало энтропии)
  • инкрементировались относительно последнего значения

Это не обязательно выглядело как token = time(), но суть равна: если у тебя есть несколько токенов разных пользователей, ты можешь восстановить последовательность и предсказать следующие.

Это классическая уязвимость: предсказуемый seed + короткий токен = чужой аккаунт

Как это эксплуатировалось?

Атакующий мог:

  1. Запросить сброс паролей нескольких своих аккаунтов.
  2. Получить токены.
  3. Вычислить закономерность.
  4. Сгенерировать токены для других ID.
  5. Переходить по ссылкам сброса без запроса.

То есть можно было не просить сброс пароля, а просто сформировать ссылку, по которой система скажет: «Да, токен ваш».

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

Почему это произошло?

Потому что разработчики допустили три классические ошибки:

1. Использовали PRNG, а не CSPRNG.

2. Сидировали генератор gпредсказуемыми данными.

3. Токен был коротким.

Плюс - токены не были связаны с одноразовой сессионной привязкой, поэтому система принимала их «в вакууме», а не в контексте запроса.

Как нужно делать правильно

  1. Использовать CSPRNG, например: crypto.getRandomValues() /dev/urandom ChaCha20
  2. Минимум 128 бит энтропии 16 байт в hex дают 32 символа - это база.
  3. Привязывать токен к устройству/сессии/пользователю. Токен должен работать только в связке с запросом.
  4. Одноразовость: срабатывает 1 раз — и сгорает.
  5. Истекает быстро 10–30 минут, не сутки.
  6. Логировать попытки валидации, а не только выдачу.

Почему важно писать об этом в 2025 году

Потому что «предсказуемый токен» - это не ошибка эпохи PHP 5. Это ошибка людей, которые: делают регистрацию Web3-кошельков прямо в браузере, генерируют токены в Unity для F2P-игр, пишут CAPTCHA-бэкэнды через Math.random() и после этого удивляются, что аккаунты угнали.

Большинство разработчиков уверены, что безопасность - это про шифрование. Но токен "qwerty123" - это даже не про дешифровать, это просто угадать.

Случайность - это не просто число. Случайность - это гарантия, что ты не станешь чьей-то добычей.

Начать дискуссию