Підпис охоплює повний payload вебхука: id, delivered_at, event. Підтримуються два алгоритми підпису залежно від keyType:
ED25519 (Рекомендований)
- Створити об’єкт payload:
id, delivered_at, event
- JSON.stringify(payload)
- Закодувати JSON-рядок у Base64
- Підписати за допомогою ED25519 (ed25519.signAsync)
- Закодувати підпис у Base64
Legacy (Застарілий)
- Створити об’єкт payload:
id, delivered_at, event
- JSON.stringify(payload)
- Закодувати JSON-рядок у Base64
- SHA256 хеш (privateKey + data)
- Закодувати хеш у Base64
Особливості безпеки:
- Підпис охоплює всі поля, включно з id і delivered_at
- Унікальний id запобігає атакам повторного відтворення (replay attacks)
- Валідація часової мітки запобігає прийняттю застарілих вебхуків (вікно 16 хвилин)
- 16-хвилинне вікно враховує повторні спроби (негайно + 5 хв + 10 хв) + мережевий буфер
- ED25519 забезпечує криптографічну автентичність
Логіка повторної спроби
- Перша спроба: Негайно
- Друга спроба: затримка 300 секунд (5 хвилин)
- Третя спроба: затримка 600 секунд (10 хвилин)
- Помилка: задача видаляється з черги та логуються
ВАЖЛИВО: Завжди перевіряйте webhooks, щоб запобігти підробці та повторним атакам.
Повний алгоритм перевірки
Етапи перевірки ED25519
- Захист від повторного відтворення - перевірте
webhook.id, який не був помічений раніше
- Перевірка часової мітки - перевірка delivery_at протягом 16 хвилин (максимальний час доставки + буфер)
- Відновлення корисної нагрузки -
id, delivery_at, event
- Перевірка підпису - ed25519.verifyAsync (signature, payload, publicKey)
- Зберегти ідентифікатор веб-гука - зберегти для запобігання повторному відтворенню