Logo StartupKit
PL

Bezpieczeństwo i dostarczanie webhooków

Weryfikacja podpisów webhooków, mechanizm ponownych prób dostarczenia oraz rozwiązywanie problemów.

Dlaczego to ważne

Weryfikacja podpisów potwierdza, że dane są autentyczne i nie zostały zmodyfikowane. Zrozumienie mechanizmu ponownych prób i automatycznego wyłączania pomaga budować odporne integracje.

Weryfikacja podpisów

Każde dostarczenie jest podpisywane za pomocą klucza podpisu przypisanego do endpointu przy użyciu HMAC-SHA256. Podpis obejmuje znacznik czasu oraz treść żądania, co zapobiega atakom powtórkowym (replay attacks).

Podpisywana treść to znacznik czasu w formacie ISO 8601 i treść JSON połączone kropką:

<timestamp>.<body>

Ruby

timestamp = request.headers["X-Webhook-Timestamp"]
signature = request.headers["X-Webhook-Signature"]
body = request.body.read

expected = OpenSSL::HMAC.hexdigest("SHA256", signing_secret, "#{timestamp}.#{body}")

if ActiveSupport::SecurityUtils.secure_compare(expected, signature)
  # Signature is valid
else
  head :unauthorized
end

Node.js

const crypto = require("crypto");

function verifySignature(signingSecret, timestamp, body, signature) {
  const expected = crypto
    .createHmac("sha256", signingSecret)
    .update(`${timestamp}.${body}`)
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}

Python

import hmac
import hashlib

def verify_signature(signing_secret, timestamp, body, signature):
    expected = hmac.new(
        signing_secret.encode(),
        f"{timestamp}.{body}".encode(),
        hashlib.sha256
    ).hexdigest()

    return hmac.compare_digest(expected, signature)

Zapobieganie atakom powtórkowym

Porównaj wartość X-Webhook-Timestamp z bieżącym czasem i odrzucaj żądania starsze niż 5 minut.

Rotacja klucza podpisu

Kliknij Rotate Secret na stronie szczegółów webhooka, żeby wygenerować nowy klucz podpisu. Poprzedni klucz zostaje natychmiast unieważniony.

Żeby przeprowadzić rotację bez przestoju:

  1. Wdróż endpoint tak, aby akceptował podpisy zarówno ze starego, jak i nowego klucza
  2. Wykonaj rotację klucza w Kit
  3. Sprawdź, czy dostarczenia przebiegają pomyślnie z nowym kluczem
  4. Usuń stary klucz z endpointu

Dostarczanie i ponowne próby

Kit wysyła ładunek JSON metodą POST do Twojego endpointu z następującymi limitami czasu:

Ustawienie Wartość
Limit czasu połączenia 10 sekund
Limit czasu odczytu 15 sekund

Odpowiedź 2xx oznacza dostarczenie jako zakończone. Wszystko inne to błąd, a sposób jego obsługi przez Kit zależy od tego, czy błąd jest przejściowy, czy trwały.

Błędy przejściowe (z ponawianiem)

Błędy przejściowe to problemy, które prawdopodobnie same ustąpią — Twój endpoint był chwilowo przeciążony, przekroczył limit czasu albo był nieosiągalny. Kit ponawia je do 5 prób z wielomianowym opóźnieniem (każde oczekiwanie dłuższe od poprzedniego).

Błąd jest traktowany jako przejściowy, gdy odpowiedź to:

  • HTTP 500599 (błędy serwera)
  • HTTP 408 (Request Timeout)
  • HTTP 429 (Too Many Requests)
  • Błąd sieci lub przekroczenie limitu czasu (odrzucone połączenie, błąd DNS, timeout odczytu)
Próba Zachowanie
1 Natychmiastowa
2–5 Wielomianowo rosnące czasy oczekiwania

Błędy trwałe (bez ponawiania)

Błędy trwałe oznaczają, że samo żądanie jest nie do przyjęcia dla Twojego endpointu i ponawianie nic nie da. Kit od razu oznacza dostarczenie jako błędne i go nie ponawia.

Błąd jest traktowany jako trwały, gdy odpowiedź to dowolny inny status 4xx — na przykład 400, 401, 404 lub 410. Jeśli Twój endpoint zwraca taki kod przez pomyłkę, popraw trasę lub uwierzytelnianie po swojej stronie; Kit ponowi próbę dopiero przy następnym zdarzeniu.

Automatyczne wyłączanie

Po 15 kolejnych nieudanych dostarczeniach (niezależnie od typu zdarzenia) Kit automatycznie wyłącza webhooka.

Po wyłączeniu:

  • Dalsze próby dostarczenia nie są podejmowane
  • Status zmienia się na Disabled ze znacznikiem czasu disabled_at

Kliknięcie Resume ponownie aktywuje webhooka. Powoduje to zresetowanie licznika błędów i przywrócenie webhooka do stanu aktywnego.

Logi dostarczania

Każdy endpoint webhooka ma zakładkę Deliveries pokazującą 50 ostatnich dostarczeń. Każdy wpis zawiera:

Pole Opis
Zdarzenie Typ zdarzenia, które wywołało dostarczenie
Status pending, in_progress, completed lub errored
Liczba prób Liczba prób dostarczenia
Nagłówki żądania Nagłówki wysłane wraz z żądaniem
Odpowiedź Kod statusu HTTP lub komunikat błędu
Znacznik czasu Data i godzina utworzenia dostarczenia

Statusy dostarczenia

Status Znaczenie
pending Utworzone, oczekuje na wysłanie
in_progress W trakcie dostarczania
completed Endpoint zwrócił odpowiedź 2xx
errored Wszystkie ponowne próby wyczerpane lub endpoint zwrócił błąd trwały (4xx)

Przechowywanie danych

Logi dostarczania są przechowywane przez 30 dni, a następnie automatycznie usuwane. Jeśli potrzebujesz dłuższego przechowywania, zapisuj ładunki po swojej stronie.

Wymagania dotyczące adresów URL

  • Wymagany protokół HTTPS — endpointy HTTP są odrzucane
  • Tylko publiczne adresy IP — adresy URL prowadzące do adresów prywatnych (localhost, 10.x.x.x, 192.168.x.x itp.) są blokowane
  • Adresy URL są walidowane podczas tworzenia oraz przed każdym dostarczeniem

Rozwiązywanie problemów

Problem Przyczyna Rozwiązanie
Niezgodność podpisu Nieprawidłowy klucz podpisu lub treść zmodyfikowana przed weryfikacją Zweryfikuj podpis na podstawie surowej treści żądania z aktualnym kluczem
Przekroczenie limitu czasu dostarczenia Endpoint potrzebuje więcej niż 15 sekund Zwróć 200 natychmiast i przetwórz dane asynchronicznie
Dostarczenie z błędem bez ponowienia Endpoint zwrócił trwały 4xx (np. 404, 410) Popraw trasę, uwierzytelnianie lub metodę; ponawiane są tylko błędy przejściowe (5xx, 408, 429, sieć/timeout)
Webhook automatycznie wyłączony 15 kolejnych niepowodzeń Napraw endpoint, a następnie kliknij Resume
Adres URL odrzucony Prywatny adres IP lub protokół HTTP Użyj adresu HTTPS prowadzącego do publicznego adresu IP
Zdarzenia nie są wyzwalane Webhook wstrzymany lub typ zdarzenia nie jest subskrybowany Sprawdź status webhooka i zasubskrybowane zdarzenia

W skrócie

  • Skopiuj klucz podpisu ze strony szczegółów webhooka
  • Zaimplementuj weryfikację podpisu HMAC-SHA256 w endpoincie
  • Odrzucaj żądania ze znacznikami czasu starszymi niż 5 minut
  • Zwracaj kod statusu 2xx w ciągu 15 sekund
  • Obsługuj ponowne próby w sposób idempotentny (to samo zdarzenie może zostać dostarczone więcej niż raz)
  • Monitoruj logi dostarczania pod kątem błędów
  • Skonfiguruj alerty na wypadek automatycznego wyłączenia webhooka

Wpisz, aby wyszukać...