Заказать
Все кейсы
Кейс 07 / 08CRITICAL · CVSS 8.8
Платёжный сервис фиат-крипто

Заказ «оплачен», хотя денег никто не платил

Провайдер давно отключён. А его канал уведомлений об оплате продолжал работать.

Заказчик: · NDA

  • Доступанонимно
  • Оповещениене сработало
  • Деньгине двигали
NEW → SUCCESSстатус платежа без оплаты
Заказ № 10482
Сумма заказа · 500 USDTЖдёт оплаты
NEW
Денег за заказ никто не платил
Оплата начата у провайдераожидание
Уведомление от отключённого провайдерабез подписи
500 USDT к отправкев очереди
После исправления: уведомление без подписи отклонено
01

О продукте

Платформа подключала больше 20 платёжных провайдеров. Каждый сообщал результат оплаты через публичный callback — запрос к API платформы. После отключения части провайдеров маршруты их уведомлений продолжали работать.

02

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

Один старый маршрут принимал GET-запрос с номером платежа без подписи. Обработчик искал платёж только по этому номеру. Он не проверял, совпадает ли провайдер уведомления с провайдером, который обслуживает платёж.

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

03

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

  • Товар уходит без оплаты
  • Финансовые записи расходятся с деньгами
  • Сверка не видит подмену
04

Как доказали

На тестовой среде анонимный GET-запрос перевёл платёж из NEW в SUCCESS без обращения к его провайдеру. Проверка подтвердила именно подмену между каналами: старый маршрут завершил платёж действующего канала.

В боевой проверке журнал также записал чужого провайдера для платежа; оповещение не сработало. Вывод криптовалюты остановили проверки адреса KYT/KYC. Проверка подлинности уведомления этот риск не блокировала.

05

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

Старые маршруты живы и без подписи

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

Подпись на каждом уведомлении

  • Старые маршруты удалили; на действующих проверяется подпись провайдера
  • Провайдер уведомления сверяется с провайдером платежа до смены статуса
  • Во внешнем API используются случайные идентификаторы платежей
  • Добавили оповещение о несовпадении провайдеров
Урок

Отключённая интеграция живёт, пока отвечает её адрес.

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

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

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

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