Skip to main content
Проверка подписи вебхука — необходимый минимум, но не полная защита. Эта инструкция про то, что кусает уже в проде и стоит денег: защиту от повторного проигрывания (replay), перепроверку статуса перед выдачей ценного, и оставшиеся острые углы приёма вебхуков. Базовая проверка подписи описана в Настройке вебхуков и Объекте вебхука — здесь мы идём глубже и не повторяем её.

Что подпись НЕ гарантирует

Верная подпись доказывает две вещи: тело пришло от Oblodai и не изменено в пути. Она не гарантирует:
  • что это уведомление свежее, а не перехваченное и проигранное заново позже (replay);
  • что описанное в теле состояние всё ещё актуально к моменту, когда вы его обрабатываете;
  • что вы не обрабатываете это событие повторно (доставка at-least-once).
Каждый пункт закрывается отдельно.

1. Replay-защита по timestamp

В каждой доставке есть заголовок X-Webhook-Timestamp — момент отправки в unix-секундах, и он входит в подписанную строку (hex(HMAC-SHA256(secret, "{timestamp}." + сырое_тело))). Значит, timestamp нельзя подменить, не сломав подпись. Используйте это: отклоняйте вебхуки со слишком старым timestamp. Тогда даже валидно подписанное, но перехваченное ранее уведомление нельзя будет проиграть спустя время.
Про окно и ретраи. X-Webhook-Timestamp обновляется на каждой попытке доставки — при ретрае Oblodai переподписывает тело со свежей меткой времени. Поэтому окно 300 секунд не отбраковывает легитимные повторы (даже если сам ретрай случился через час): каждая доставка «свежая» на момент отправки. 300 c — разумная отправная точка; сужать окно ради «защиты от ретраев» не нужно.

2. Дедупликация — защита от повторной обработки

Доставка at-least-once: одно событие может прийти несколько раз (в том числе после /v1/payment/resend или ретраев). Дедуплицируйте по паре uuid + status и обрабатывайте повтор как no-op.
Ключ должен жить в надёжном хранилище (БД), а не в памяти процесса — иначе после рестарта дедуп сбросится. Порядок доставок не гарантирован: опирайтесь на status/is_final, а не на очерёдность.

3. Перепроверка статуса перед выдачей ценного

Вебхук — сигнал «сходи и проверь», а для дорогих действий (отгрузка товара, крупное зачисление, разблокировка услуги) — не единственный источник правды. Перед необратимой выдачей перепроверьте состояние авторитетным запросом:
Это закрывает случаи, когда состояние изменилось между отправкой вебхука и его обработкой у вас, и добавляет второй независимый барьер к проверке подписи. Для мелких/некритичных событий такой шаг можно опустить — решайте по цене ошибки.

4. Приёмник: острые углы

  • Только HTTPS, публичный адрес. При регистрации URL проходит SSRF-проверку (приватные/локальные адреса запрещены). → /v1/webhooks
  • Сырое тело до парсинга. Подпись считается по байтам; фреймворк, который пересериализует JSON, сломает проверку (express.json() на роуте вебхука — частая ошибка).
  • Секрет вебхука — это секрет. Храните его как ключ API. Помните: повторный вызов /v1/webhooks меняет URL и выдаёт новый секрет — старый перестанет подходить.
  • Пробные тела не подписаны (is_test: true). Ваш код должен их отличать и не проверять подписью — но и не выполнять по ним реальную выдачу. → Отладка вебхуков
  • 2xx только после успешной обработки. Иначе Oblodai повторит доставку (это фича, не баг).
  • Отвечайте быстро, обрабатывайте асинхронно. Тяжёлую работу выносите в очередь, а вебхуку отвечайте 2xx сразу после того, как надёжно приняли событие — так вы не упрётесь в таймауты доставки и ретраи.

Мини-чек-лист безопасности вебхуков

  • Подпись проверяется по сырому телу правильным алгоритмом (timestamp + . + тело).
  • Секрет — из /v1/webhooks, не ключ API.
  • Проверяется свежесть по X-Webhook-Timestamp (replay-защита).
  • Дедуп по uuid + status в надёжном хранилище (не в памяти).
  • Для дорогих операций — перепроверка статуса через */info.
  • Пробные тела (is_test) отсекаются от реальной выдачи.
  • 2xx возвращается только после успешной обработки.
  • Endpoint только HTTPS, тяжёлая работа — асинхронно.

Связанные страницы

Настройка вебхуков

Объект вебхука

Отладка вебхуков

Рецепт устойчивого клиента

Безопасность в проде