Logo StartupKit
PL
Integrations

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

Należy porównać wartość X-Webhook-Timestamp z bieżącym czasem i odrzucić żądania starsze niż 5 minut.

Rotacja klucza podpisu

Aby wygenerować nowy klucz podpisu, należy kliknąć Rotate Secret na stronie szczegółowej webhooka. Poprzedni klucz zostaje natychmiast unieważniony.

Aby przeprowadzić rotację bez przestoju:

  1. Wdrożyć endpoint tak, aby akceptował podpisy zarówno ze starego, jak i nowego klucza
  2. Dokonać rotacji klucza w Kit
  3. Sprawdzić, czy dostarczenia przebiegają pomyślnie z nowym kluczem
  4. Usunąć stary klucz z endpointu

Dostarczanie i ponowne próby

Kit podejmuje do 5 prób dostarczenia, gdy endpoint jest niedostępny lub zwraca błąd.

Próba Zachowanie
1 Natychmiastowa
2-5 Wielomianowo rosnące czasy oczekiwania
Ustawienie Wartość
Limit czasu połączenia 10 sekund
Limit czasu odczytu 15 sekund

Odpowiedź 2xx oznacza dostarczenie jako zakończone. Każdy inny kod statusu lub przekroczenie limitu czasu oznacza dostarczenie jako błędne i uruchamia ponowną próbę.

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 posiada zakładkę Deliveries prezentującą 50 ostatnich dostarczeń. Każdy wpis zawiera:

Pole Opis
Event Typ zdarzenia, które wywołało dostarczenie
Status pending, in_progress, completed lub errored
Attempts Liczba prób dostarczenia
Request headers Nagłówki wysłane wraz z żądaniem
Response Kod statusu HTTP lub komunikat błędu
Timestamp 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

Przechowywanie danych

Logi dostarczania są przechowywane przez 30 dni, a następnie automatycznie usuwane. Aby zachować dane dłużej, należy zapisywać ł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ą Zweryfikować podpis na podstawie surowej treści żądania z aktualnym kluczem
Przekroczenie limitu czasu dostarczenia Endpoint potrzebuje więcej niż 15 sekund Zwrócić 200 natychmiast i przetworzyć dane asynchronicznie
Webhook automatycznie wyłączony 15 kolejnych niepowodzeń Naprawić endpoint, a następnie kliknąć Resume
Adres URL odrzucony Prywatny adres IP lub protokół HTTP Użyć adresu HTTPS prowadzącego do publicznego adresu IP
Zdarzenia nie są wyzwalane Webhook wstrzymany lub typ zdarzenia nie jest subskrybowany Sprawdzić status webhooka i zasubskrybowane zdarzenia

Szybka lista kontrolna

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

Wpisz, aby wyszukać...