Заказать
Все кейсы
Кейс 02 / 08CRITICAL · CVSS 9.1
Крипто-приложение · некастодиальный кошелёк

Вход в любой чужой аккаунт

Пароль, телефон и почта жертвы не нужны. Хватало публичных данных из блокчейна.

Заказчик: · NDA

  • Доступанонимно
  • Затронутывсе EVM-кошельки
  • Исправленоза сутки
1 запросчтобы войти в аккаунт любого пользователя
Активные сессии
Сессии аккаунтаАккаунт защищён
1 устройство
Уведомления владельца уходят на чужой телефон
iPhone владельцасейчас
Неизвестное устройство, вход без паролясейчас
После исправления: 401, вход отклонён
01

О продукте

Мобильное приложение для покупки и обмена криптовалют. Приватные ключи хранятся только на устройстве пользователя. Регистрация и вход используют один API-запрос: сервер проверяет цифровую подпись и выдаёт токены сессии.

02

Где была ошибка

Сервер проверял подпись по расширенному публичному ключу xpub, а аккаунт выбирал по отдельному полю publicKey. Связь между полями не проверялась. Подпись собственным ключом проходила проверку, но сервер выдавал сессию чужого аккаунта.

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

03

Чем это грозило

  • Чтение профиля, балансов и истории операций
  • Перехват уведомлений пользователя
  • Подмена привязанного адреса кошелька
  • Утечка клиентской базы и регуляторный риск

Вывести деньги злоумышленник не мог: для этого нужна подпись с телефона пользователя.

04

Как доказали

На тестовой среде с тем же кодом запрос вернул HTTP 200 и JWT чужого тестового аккаунта. Сессия открывала профиль, историю операций и балансы. Также подтвердили подмену адреса кошелька и перенаправление push-уведомлений.

После исправления повторили проверку: подменный вход вернул 401, обычный вход продолжил работать. Данные реальных пользователей не затрагивали.

05

Как исправили

Подменный вход: 200 OK

  • Аккаунт выбирался по полю клиента без связи с подписью
  • Подпись входа работала бессрочно и допускала повтор
  • Частота попыток входа не ограничивалась

Подменный вход: 401, отказ

  • Ключ аккаунта сверяется с ключом проверенной подписи
  • Добавили срок действия подписи и одноразовый nonce
  • Ввели лимит попыток и сменили ключи подписи сессий
Урок

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

Исправлено
Заявка

Проверим ваш продукт до того, как это сделает кто-то другой

Опишите продукт в двух словах. Ответим в течение рабочего дня и предложим формат: чёрный или белый ящик.

  • Договор и NDA до начала работ
  • Отчёт для бизнеса и для разработчиков
  • Повторная проверка после исправления