Każde żądanie webhooka zawiera nagłówek X-Infakt-Signature: podpis HMAC-SHA256 surowej treści żądania, wyliczony sekretnym kluczem webhooka i zapisany szesnastkowo. Sekretny klucz powstaje automatycznie i jest widoczny w szczegółach webhooka w aplikacji WWW ↗.
Aplikacja odbierająca zdarzenie wylicza HMAC z otrzymanej treści własną kopią klucza. Zgodność wyniku z nagłówkiem oznacza, że żądanie wysłał inFakt i nikt go po drodze nie zmienił. Przy niezgodności należy odpowiedzieć kodem 401 i nie przetwarzać zdarzenia.
Zagrożenie bez podpisu
Adres webhooka jest publiczny, więc każdy, kto go zna, może wysłać na niego fałszywe zdarzenie „faktura opłacona”. Aplikacja bez weryfikacji podpisu uznałaby wtedy zamówienie za zapłacone. Podpis wiąże treść z sekretem, którego atakujący nie zna.
Ograniczenia
- Podpis wylicza się z surowej treści żądania, bajt po bajcie. JSON sparsowany i zapisany ponownie ma inną postać i inny podpis.
- Podpisy porównuje się funkcją działającą w stałym czasie (
timingSafeEqual,hmac.compare_digest,hash_equals), a nie zwykłym operatorem==. - Podpis nie szyfruje treści. Treść chroni połączenie HTTPS, dlatego adres webhooka musi zaczynać się od
https://. - Podpis nie chroni przed ponownym wysłaniem tego samego, prawdziwego żądania. Przed powtórzeniami chroni sprawdzanie
event.uuid. - Sekret webhooka nie jest kluczem API. Każdy webhook ma własny sekret.