Перевірка вхідних вебхуків
Будь-хто, хто дізнався ingress-адресу джерела, може надсилати на неї запити. Перевірка звіряє кожен запит із секретом, яким підписує провайдер, і відхиляє все, що не збігається, ще до того, як щось буде збережено.
Режими перевірки
Section titled “Режими перевірки”verificationMode |
Що перевіряється |
|---|---|
NONE |
Нічого. Усе, що надійшло на адресу, Railhook зберігає й пересилає. Вмикайте цей режим лише на час підключення провайдера. |
PROVIDER |
Власна схема провайдера, яку визначає providerType. Вона є в кожного типу провайдера, крім GENERIC. |
HMAC_GENERIC |
HMAC-SHA256-підпис у заголовку, який ви вкажете. Саме так перевіряють провайдера GENERIC. |
На запит, що не пройшов перевірку, Railhook відповідає 401 і не зберігає його.
Провайдери
Section titled “Провайдери”GET /api/v1/incoming-providers повертає провайдерів, яких перевіряє запущений Railhook, і заголовок, у якому підписує кожен. Провайдера, якого немає в списку, можна додати одним класом; як саме, описано в CONTRIBUTING.md.
providerType |
Заголовок, що перевіряється | Як |
|---|---|---|
GITHUB |
X-Hub-Signature-256 |
sha256=, а за ним HMAC-SHA256 необробленого тіла в hex. |
GITLAB |
X-Gitlab-Token |
Заголовок має дорівнювати секрету. GitLab надсилає токен, а не підпис. |
STRIPE |
Stripe-Signature |
t=…,v1=…: HMAC-SHA256 від <t>.<необроблене тіло> у hex. t має відрізнятися від поточного часу не більш ніж на 300 секунд. Під час ротації секрету Stripe надсилає по одному v1 на кожен секрет; запит проходить перевірку, якщо збігається будь-який із них. |
SHOPIFY |
X-Shopify-Hmac-SHA256 |
HMAC-SHA256 необробленого тіла в Base64. |
SLACK |
X-Slack-Signature, X-Slack-Request-Timestamp |
v0=, а за ним HMAC-SHA256 від v0:<timestamp>:<необроблене тіло> у hex. Мітка часу має відрізнятися від поточного часу не більш ніж на 300 секунд. |
TWILIO |
X-Twilio-Signature |
HMAC-SHA1 в Base64, ключ — Auth Token. Для запитів у форматі form-encoded підписано URL, а за ним усі параметри, відсортовані за назвою; для інших запитів — лише URL, а параметр рядка запиту bodySHA256 має відповідати тілу. |
| SQUARE | x-square-hmacsha256-signature | HMAC-SHA256 у Base64 від адреси сповіщення, за якою одразу йде необроблене тіло, без жодного роздільника. |
| ADYEN | hmacsignature або жодного | HMAC-SHA256 у Base64, ключ — декодовані байти hex-ключа HMAC. Стандартний платіжний вебхук не має заголовка взагалі: кожен елемент сповіщення підписує вісім власних полів, з’єднаних двокрапками, і кладе результат у additionalData.hmacSignature. Вебхуки Management і Balance Platform підписують необроблене тіло й передають підпис у заголовку. Railhook приймає обидві схеми, тож одне джерело впорається з будь-якою. |
| SENDGRID | X-Twilio-Email-Event-Webhook-Signature, X-Twilio-Email-Event-Webhook-Timestamp | ECDSA над SHA-256 від мітки часу, за якою йде необроблене тіло; перевіряється відкритим ключем SendGrid. Це не HMAC. |
| HUBSPOT | X-HubSpot-Signature-v3, X-HubSpot-Request-Timestamp | HMAC-SHA256 у Base64 від методу запиту, повної адреси, необробленого тіла й мітки часу — саме в такому порядку, ключ — client secret застосунку. Мітка часу має відрізнятися від поточного часу не більш ніж на 300 секунд. Підтримано лише v3: v1 і v2 не прив’язують запит до жодного моменту. |
Для будь-якого провайдера секрет указують у полі hmacSecret джерела: секрет підпису вебхуків, секретний токен (Secret token) GitLab, Auth Token Twilio, Signature Key у Square, ключ HMAC Adyen у вигляді того самого шістнадцяткового рядка, який показує Customer Area, або client secret застосунку HubSpot.
Налаштування провайдера
Section titled “Налаштування провайдера”-
Створіть джерело з
verificationMode:PROVIDER, потрібнимproviderTypeі секретом провайдера:Terminal window curl -X POST "$RAILHOOK_URL/api/v1/projects/$PROJECT_ID/incoming-sources" \-H "X-API-Key: $API_KEY" \-H "Content-Type: application/json" \-d '{"name":"GitHub","providerType":"GITHUB","verificationMode":"PROVIDER","hmacSecret":"'"$GITHUB_WEBHOOK_SECRET"'"}' -
Вставте
ingressUrlджерела в налаштування вебхуків провайдера з тим самим секретом. -
Надішліть тестовий вебхук із боку провайдера. Він з’явиться в розділі «Отримані»; якщо підпис не збігся, Railhook відповість
401і вебхука там не буде.
Загальний HMAC
Section titled “Загальний HMAC”Для провайдера без готового пресету використовуйте HMAC_GENERIC:
| Поле | Типово | Значення |
|---|---|---|
hmacHeaderName |
X-Signature |
Заголовок із підписом. |
hmacSignaturePrefix |
немає | Префікс, який Railhook відкидає перед порівнянням, наприклад sha256=. |
hmacSecret |
Спільний секрет. |
Railhook приймає заголовок у двох форматах:
| Формат | Що підписано | Захист від повторного використання |
|---|---|---|
t=<unix-ms>,v1=<hex>, власний формат Railhook |
<t>.<необроблене тіло> |
t має відрізнятися від поточного часу не більш ніж на 300 секунд. |
| Лише hex-дайджест | Лише необроблене тіло | Сам підпис не захищає: той самий запит проходитиме перевірку, доки діє секрет. |
curl -X POST "$RAILHOOK_URL/api/v1/projects/$PROJECT_ID/incoming-sources" \ -H "X-API-Key: $API_KEY" \ -H "Content-Type: application/json" \ -d '{"name":"Acme","providerType":"GENERIC","verificationMode":"HMAC_GENERIC","hmacHeaderName":"X-Acme-Signature","hmacSignaturePrefix":"sha256=","hmacSecret":"'"$ACME_SECRET"'"}'Повторне використання підписів
Section titled “Повторне використання підписів”Railhook пам’ятає перевірений підпис протягом певного вікна й відхиляє з 401 другий запит із тим самим підписом у межах цього вікна. Для провайдерів, у підписі яких є мітка часу, це відсікає дублікати. Для голого hex-дайджесту це єдиний захист від того, що перехоплений запит надішлють ще раз.
Запит з ідентифікатором події провайдера, яку Railhook уже зберіг, — це повторне надсилання, а не повторне використання підпису: він однаково має пройти перевірку, після чого Railhook відповідає 202 зі збереженою подією. Див. повторні надсилання від провайдера.
| Змінна | Типово |
|---|---|
WEBHOOK_INGRESS_REPLAY_WINDOW_MINUTES |
5 |