Вебхук принимал оплату на веру — как это может быть у вас
В рассылке пришло сообщение о том, что вебхук ЮKassa принимал оплату на веру — достаточно было отправить один curl, чтобы бронь считалась оплаченной. Понял, что это не про «как работает ЮKassa», а про то, как легко сломать систему, если не проверять источник события.
О чём речь и почему я считаю это важным для сайта
Речь о том, что система принимала оплату на веру — верила, что событие `payment.succeeded` пришло от банка, хотя могло прийти от любого пользователя. Даже не от хакера, а от обычного клиента, который просто открыл бронь и скопировал `id` из ответа. Это не уязвимость в API, а фундаментальная ошибка в логике. На мой взгляд, важнее другое: если вы принимаете внешние события без проверки — вы уже на грани. Даже если сейчас всё работает, завтра может не работать. И не из-за бага, а из-за того, что кто-то решил использовать вашу систему по-своему.
Как это устроено — что тут вообще происходит
Система смотрела только на `event: payment.succeeded` в теле запроса. Никакой проверки по IP, подписи или статусу у платёжного шлюза. Достаточно было знать `id` платежа — и можно было подделать оплату. Всё, что нужно — один curl. Никаких сложных инструментов, никаких бэкдоров. Просто отправить запрос с нужным `id` и статусом. И бронь становилась оплаченной. Это не ошибка в коде — это отсутствие проверки источника. Система не спрашивала: «А точно ли это от ЮKassa?» — она просто верила.
Как понять, что это касается вашего сайта («как я это проверяю»)
Я смотрю на все вебхуки, которые принимают события от внешних сервисов. Если в коде есть проверка только по полю из тела запроса — без обратного вызова к API, без проверки подписи, без IP-фильтра — это красный флаг. У меня на поддержке такие моменты проверяются первым делом. Даже если вы используете ЮKassa, Stripe или другой сервис — если логика принимает событие без проверки у источника, это уязвимость. Я уже начал обновлять WordPress у своих клиентов — не потому что там есть дыра, а потому что там могут быть такие же уязвимости в плагинах.
Что с этим делать («что я делаю в таких случаях»)
Первое — не верить телу запроса. Второе — всегда делать обратный вызов к API сервиса. Третье — не полагаться на IP-адреса, если у вас реверс-прокси. Четвёртое — проверять, что статус и сумма в ответе API совпадают с тем, что в базе. Пятый — не пытаться всё исправить за один PR. Я оставляю на потом IP-фильтр и подпись, потому что один большой диф — это риск. Лучше сделать маленький, проверяемый, с возможностью отката. И да — тесты не ловят такие ошибки. Они проверяют логику, а не доверие к внешнему источнику.
Что здесь даёт поддержка
На нашей поддержке мы не ждём, когда сайт упадёт. Мы проверяем, как обрабатываются внешние события — вебхуки, API-вызовы, формы. Если есть возможность подделать что-то, мы это находим. Главный итог не «мы починим», а «вы перестанете думать о сайте». Мы работаем с 2002 года, более 100 клиентов по всему миру. Приглашаем на бесплатный аудит сайта.