Nazaj na blog

Varno sprejemanje webhookov: podpisi, ponovitve in ponovni poskusi

September 19, 2026 10 min branja
Varno sprejemanje webhookov: podpisi, ponovitve in ponovni poskusi
Nazadnje posodobljeno:

Uredniški termin: 18. 9. 2026. Objavljeno 19. 9. 2026 po pregledu.

Sprejemnik webhookov mora vsak vhodni zahtevek obravnavati kot nezaupanja vreden, dokler podpisa ponudnika ne preveri nad natanko tistimi bajti, ki jih je prejel. Nato mora zavrniti zastarele zahtevke, pred stranskim učinkom trajno zabeležiti identiteto dostave in dogodek obdelati asinhrono. Tak vrstni red je praktičen odgovor na ponarejene webhooke, napade s ponovitvijo, ponovne poskuse in podvojene dostave.

TLS je potreben za zaščito prenosa, vendar sam ne dokaže, da je aplikacijski zahtevek poslal pričakovani ponudnik. Končna točka lahko še vedno prejme izdelan POST od kogar koli, ki jo lahko doseže. Veljaven podpis po pravilih ponudnika poveže njegov podpisni skrivni ključ z določenim vhodom, običajno z izvirnim telesom in včasih s časovnim žigom ali drugimi glavami. S tem preveri izvor in celovitost zahtevka. Ne dokazuje pa, da je dogodek primeren za vsako poslovno dejanje v aplikaciji.

Štiri stopnje dokazovanja: Izvirni zahtevek, Preveri podpis, Preveri čas, Zabeleži ID

Ohranite izvirne bajte telesa

Telo zahtevka preberite in ohranite pred razčlenjevanjem JSON, pretvorbo znakov, ponovnim zapisom JSON, spremembo stiskanja ali posegom posredne programske opreme ogrodja. Podpis preverite nad tem ohranjenim zaporedjem bajtov in nad točno določenimi glavami, ki jih zahteva ponudnik. JSON razčlenite šele po uspešnem preverjanju.

To je pogost vzrok za lažne napake in nevarne obvode. Razvijalec vidi neuspešno preverjanje, razčleni JSON, ga znova zapiše in poskuša podpisati novo besedilo. S tem ustvari drugo sporočilo. Presledki, vrstni red ključev, ubežne sekvence, obravnava Unicode in prelomi vrstic lahko spremenijo podpisni vhod. Stripe izrecno zahteva neobdelano telo in opozarja, da sprememba povzroči neuspeh preverjanja; Slack prav tako zahteva pridobitev izvornega telesa pred deserializacijo. Dokumentacija Stripe za webhooke Dokumentacija Slack za preverjanje zahtevkov

Pot webhooka usmerite pred splošno programsko opremo za razčlenjevanje teles ali jo nastavite tako, da za to pot izpostavi surov medpomnilnik. Dodatno kopijo ustvarite samo, če jo poznejši deli res potrebujejo. Zaščitite tudi dnevnike: izvorno telo lahko vsebuje osebne podatke, žetone ali poslovne zapise. Privzeto beležite korelacijsko vrednost zahtevka, ID dostave ponudnika, izid preverjanja in skrbno izbrano kodo napake, ne pa celotnega tovora.

Natančno izvedite protokol ponudnika

Ne izumljajte univerzalnega recepta za HMAC. Vsak ponudnik določi ime glave, različico podpisa, kodiranje, podpisni vhod, dovoljene algoritme in včasih več podpisov. Uporabite uradno knjižnico, kadar ustreza vašemu okolju, ali natančno izvedite dokumentirani protokol in ga preizkusite z uradnimi testnimi vrednostmi.

Glavo s podpisom razčlenite po pravilih ponudnika. Glava lahko vsebuje več podpisov ali shem. Dodatno shemo prezrite le, kadar protokol to izrecno dovoljuje, zahtevajte vsaj en veljavni podpis podprte sheme in zahtevek zavrnite, če ga ni. Stripeovi testni dogodki lahko vsebujejo veljaven podpis v1 in namenoma neveljaven v0, zato mora sprejemnik preveriti v1, ne pa zavrniti cele glave samo zaradi v0. Navodila Stripe za preverjanje podpisa

GitHub na primer opisuje X-Hub-Signature-256 kot izvleček HMAC SHA-256 nad tovorom s skrivnim ključem webhooka ter svetuje primerjavo v konstantnem času namesto navadnega operatorja enakosti. Kjer izvedba določa kodiranje, svetuje tudi obravnavo UTF-8. Dokumentacija GitHub za preverjanje webhookov Primerjava v konstantnem času je smiseln majhen ukrep po izračunu pričakovanega podpisa; ne nadomesti preverjanja pravih bajtov, algoritma in skrivnega ključa.

Zavrnite nepravilne zahtevane glave, manjkajoče skrivne ključe, neveljavna kodiranja, nepodprte zahtevane protokole in neuspešne primerjave, preden dogodek pride do poslovne logike. Ne zavrnite veljavnega podpisa podprte sheme samo zato, ker ista glava vsebuje dodatno shemo, ki jo ponudnik dovoljuje prezreti. Odgovor naj bo skladen s pričakovanji ponudnika, vendar ne razkrivajte, ali je bil določen skrivni ključ, različica ključa ali del polja skoraj pravilen. Podrobna diagnostika sodi v zaščitene notranje dnevnike.

Čas vključite v obrambo pred ponovitvami

Napadalec lahko zajame veljaven zahtevek in ga pošlje znova. Kadar ponudnik podpiše časovni žig kot del podpisnega vhoda, najprej preverite podpis, nato pa glede na sinhronizirano uro strežnika uporabite omejeno okno svežosti. Zavrnite nepravilno zapisane časovne žige, žige, ki so predolgo v preteklosti, in žige, ki so neverjetno daleč v prihodnosti. Natančna velikost okna je odločitev, vezana na ponudnika in razpoložljivost, ne čarobna številka.

Stripe opisuje časovni žig v podpisni glavi in privzeto petminutno toleranco v svojih knjižnicah. Opozarja, da toleranca nič izključi preverjanje svežosti, ter navaja, da ponovni poskus dostave dobi nov časovni žig in podpis. Slackov vodnik za preverjanje prav tako uporablja petminutni primer in pojasnjuje, da podpisani časovni žig varuje pred napadi s ponovitvijo. Navodila Stripe za preprečevanje ponovitev Navodila Slack za preprečevanje ponovitev

Časovno okno omeji obdobje, v katerem je zajeti zahtevek uporaben. Ne zagotovi obdelave natanko enkrat. Veljavni zahtevek lahko prispe večkrat znotraj dovoljenega okna, zakoniti ponovni poskusi ponudnika pa lahko prispejo pozneje z novo podpisanim časovnim žigom. Zato je pomemben nadzor ure: strežnik z zamaknjeno uro lahko zavrača dobre dogodke ali stare zahtevke sprejema dlje, kot je predvideno.

Vsak protokol ne podpiše časovnega žiga. V takem primeru poljubna glava dostave ni popolna zaščita pred ponovitvijo. Ugotovite, katera polja so v avtenticiranem vhodu. GitHub dokumentira HMAC nad telesom tovora, zato bi bilo glavo dostave zunaj tega vhoda mogoče spremeniti, veljavni podpis telesa pa bi ostal nespremenjen. Nepodpisano glavo uporabljajte le za korelacijo. Ključ podvojitve vežite na avtenticirano vsebino ali avtoritativno stanje ponudnika in uporabite trajno poslovno idempotentnost. To je izvedbeni sklep na podlagi GitHubovega dokumentiranega podpisnega vhoda. Dokumentacija GitHub za preverjanje webhookov

Idempotentnost prepreči podvojene učinke

Sprejemnik načrtujte za dostavo vsaj enkrat. Izpadi omrežja, časovne omejitve, ponovni poskusi ponudnika, ponovitve čakalne vrste in operativna ponovna pošiljanja lahko pomenijo, da isti poslovni dogodek doseže obdelovalnik več kot enkrat. Za ključ podvojitve ne uporabljajte časa prihoda ali časa nastanka dogodka pri ponudniku. Dogodki so lahko izven vrstnega reda, ločeni dogodki pa imajo lahko enako časovno vrednost.

Kadar obstaja, uporabite nespremenljivi ID dogodka ali dostave, ki ga določi ponudnik, potem ko ugotovite, ali je vezan na avtenticirano vsebino. Shranite omejen zapis prejema z omejitvijo enoličnosti, nato pred uspešnim potrdilom dostave trajno shranite stanje prejeto in zapis dela. Konflikt ne pomeni samodejno dokončanja: delo v stanjih prejeto in v obdelavi obnovite ali nadaljujte; brez novega dela potrdite le že dokončan ali varno zaključen zapis. Stripe priporoča beleženje že obdelanih ID-jev dogodkov in navaja, da lahko končne točke prejmejo isti dogodek več kot enkrat. Navodila Stripe za podvojene dogodke

Nekateri ponudniki lahko ustvarijo različne ovojnice dogodkov za isti osnovni objekt. Takrat sam ID dogodka morda ne zadošča poslovnemu pravilu. Drugi domenski ključ določite samo, kadar ga upravičuje semantika dogodkov ponudnika, na primer (ID objekta ponudnika, tip dogodka, podprta različica); ne blokirajte zakonitih sprememb stanja samo zato, ker omenjajo isti objekt. Kadar je vrstni red pomemben, pridobite trenutno stanje iz avtoritativnega API-ja ali poslovni prehod omejite na pričakovano prejšnje stanje.

Čakalna vrsta te zahteve ne odpravi. Omogoči hitro potrditev sprejema in poznejše počasnejše delo, vendar je njena dostava pogosto tudi vsaj enkratna. Delavec potrebuje obnovljiva stanja prejeto, v obdelavi, dokončano in napaka za ponovni poskus ter iztek zaklepa ali drug mehanizem za obnovitev po sesutju. Kadar je mogoče, v eni transakciji shranite lokalni prejem, prehod stanja in sporočilo za odhodno čakalno vrsto. Ta trajni lokalni prenos ne more atomsko potrditi plačila, e-pošte, dodelitve dostopa ali drugega klica zunanjemu sistemu.

Za zunanji učinek uporabite stabilen idempotentnostni ključ, kadar ga ciljni API podpira, in ga shranite ob zapisu dela. Če se delavec sesuje po sprejemu operacije v zunanjem sistemu, vendar pred lokalnim zapisom dokončanja, zahtevek ponovite ali pri zunanjem sistemu preverite rezultat z istim ključem, nato uskladite lokalno stanje. Če ključ ali preverljiv rezultat nista na voljo, dokumentirajte preostalo tveganje podvojitve in uporabite usklajevanje, kompenzacijske ukrepe ali drugačen potek dela. Omejitev enoličnosti in odhodna čakalna vrsta sami ne zagotavljata natanko ene zunanje izvedbe.

Podpisne ključe zamenjajte s prekrivanjem

Skrivni ključ je poverilnica. Hranite ga v upravljalniku skrivnosti ali enakovredni zaščiteni konfiguraciji, omejite ga na končno točko in ga ne shranjujte v izvorni kodi ali običajnih dnevnikih zahtevkov. GitHub izrecno pravi, da je treba skrivni ključ webhooka hraniti varno in ga ne smete vgraditi v kodo ali poslati v repozitorij. Navodila GitHub za hrambo skrivnega ključa

Menjava ključa je nadzorovana sprememba, odvisna od ponudnika. Če je nadomestni ključ pripravljen vnaprej, ga namestite v sprejemnik, preden ga aktivirate pri pošiljatelju. Če ponudnik nadomestni ključ ustvari šele ob začetku menjave, sprožite njegov postopek, novi ključ pridobite po odobreni poti in ga hitro namestite, medtem ko dokumentirano prekrivanje ohranja uporabnost starega ključa. Med prekrivanjem sprejmite podpis, ki se preveri s katerim koli odobrenim aktivnim ključem, in beležite le neobčutljivo oznako ključa.

Stari ključ obdržite samo za dokumentirano obdobje prekrivanja in za ozko utemeljen čas zahtevkov, ki so že na poti, če ga protokol potrebuje. Ne obdržite ga za celotno obdobje ponovnih poskusov samo zato, ker pošiljatelj lahko ponavlja: Stripe navaja, da njegovi ponovni poskusi dobijo nov podpis in časovni žig. Po preverjanju ga odstranite takoj. Če sumite, da je ključ ogrožen, ga takoj prekličite ali izključite in sprožite postopek za varnostni incident; ne čakajte na običajno prekrivanje.

Stripe ponuja konkreten primer: ob menjavi podpisnega skrivnega ključa lahko prejšnji ključ takoj poteče ali ostane aktiven do 24 ur, Stripe pa v tem obdobju ustvari podpis za vsak aktivni ključ. To vedenje je lastno ponudniku. Navodila Stripe za menjavo podpisnih ključev

Odločitev sprejemnika Dokaz preverjanja Odprava ob neuspehu
Izvorno telo je ohranjeno Uradni primer se preveri pred razčlenjevanjem JSON Omogočite zajem surovega telesa za to pot
Podpisni protokol se ujema Veljavni primer uspe, spremenjen bajt in podpis ne; primer z v1 in testnim v0 uspe Razčlenite dovoljene sheme in zahtevajte en ujemajoč se podprti podpis
Preverjanje ponovitve ustreza protokolu Svež podpisani primer uspe, zastareli ne; brez časovnega žiga so znana avtenticirana polja Nepodpisane glave ne uporabljajte kot dokaza proti ponovitvi
Obnovitev prejema je varna Podvojitev med nedokončanim delom se varno nadaljuje; dokončano delo se ne ponovi Ohranite trajna stanja prejeto, v obdelavi in dokončano z obnovitvijo
Zunanji učinek je obvladan Sesutje v preskusnem okolju po sprejemu učinka in pred lokalnim zaključkom se uskladi z istim ključem Pri zunanjem sistemu preverite ali ponovite z istim ključem; brez tega dokumentirajte tveganje
Menjava ključa je varna Stari in novi veljavni primeri uspejo le med dokumentiranim prekrivanjem; stari po odstranitvi ne uspe Sledite postopku ponudnika; ob kompromitiranju ključ takoj prekličite

Pogoji za zaustavitev in varen odziv

Takoj se ustavite pred razčlenjevanjem za poslovno uporabo ali ustvarjanjem dela, kadar telesa ni mogoče neokrnjeno prebrati, kadar manjka zahtevana glava, kadar ni veljavnega podpisa podprte sheme, kadar podpis ne uspe ali je podpisani časovni žig zunaj pravilnika. Kadar protokol dovoljuje dodatne sheme, njihova prisotnost ni razlog za zaustavitev, če se podprti podpis preveri. Pred stranskim učinkom se ustavite, kadar tip dogodka ni dovoljen, obseg ni znan ali poslovni predpogoji niso izpolnjeni. Obstoječi zapis prejema je točka odločitve: nedokončano delo nadaljujte, dokončano potrdite, negotov zunanji učinek pa uskladite, namesto da bi ga slepo preskočili.

Uspešen podpis mora voditi do ozkega dovoljenega seznama tipov dogodkov in shem. Po avtentikaciji preverite zahtevana polja, preslikavo najemnika in pričakovano stanje objekta. Pri dejanjih z velikim vplivom pridobite avtoritativni objekt prek API-ja ponudnika, kadar to omogočata protokol in model zakasnitve. Tako se izognete sklepanju na podlagi zastarelega tovora in preprečite, da bi webhook postal splošen kanal za avtorizacijo.

Kontrolni seznam pred produkcijo

  • Pred razčlenjevalniki zajemite telo kot bajte in preverite uradni testni primer ponudnika.
  • Preizkusite manjkajoče, nepravilne, neusklajene in spremenjene podpise; kjer velja, preizkusite veljavni v1 ob dodatnem testnem v0.
  • Preizkusite zastarele in prihodnje podpisane časovne žige. Brez podpisanega časovnega žiga dokumentirajte avtenticirana polja in dokažite, da nepodpisana glava ni dokaz proti ponovitvi.
  • Dvakrat pošljite veljavno dostavo in jo pošljite še med nedokončanim delom; dokažite, da obnovitev lokalnega dela ne izgubi ali ponovi.
  • Simulirajte sesutje po sprejemu učinka v preskusnem ali nadomestnem zunanjem sistemu, vendar pred lokalnim zapisom zaključka; uskladite ga z istim idempotentnostnim ključem.
  • Preizkusite dogodke izven vrstnega reda, ponovne poskuse, dokumentirano prekrivanje pri menjavi, zavrnitev starega ključa in takojšnji preklic ogroženega ključa.
  • Opozarjajte na neuspehe preverjanja, zavrnitve zastarelih zahtevkov, podvojene prejeme in spremembe porazdelitve oznak ključev.

Za širši pregled končne točke glejte Testiranje varnosti API-jev in Varnost spletnih aplikacij.

Pogosta vprašanja

Ali HTTPS odpravi potrebo po podpisih webhookov?

Ne. HTTPS zaščiti povezavo med prenosom, podpis webhooka pa sprejemniku omogoča preverjanje zahtevka po pravilih ponudnika. Ohranite oba ukrepa in sledite dokumentirani metodi preverjanja ponudnika.

Ali lahko veljaven podpis vsakemu dogodku dovoli spremembo naših zapisov?

Ne. Veljaven podpis avtenticira dostavo po protokolu ponudnika. Sprejemnik še vedno potrebuje dovoljen seznam dogodkov, preverjanje sheme, preslikavo najemnika, idempotentnost in preverjanje poslovnega stanja.

Ali lahko toleranco časovnega žiga izključimo, ker je podpis veljaven?

Ne. Podpis lahko ostane veljaven tudi za zajeti zahtevek. Kadar ponudnik podpiše časovni žig, je neničelno okno svežosti del obrambe pred ponovitvijo. Združite ga s trajno idempotentnostjo, saj se lahko pojavijo tudi zakoniti ponovni poskusi in podvojitve.

Vid Grosek

Vid Grosek

Etični heker & Penetracijski tester

Pomagam slovenskim podjetjem odkriti varnostne ranljivosti, preden jih odkrijejo napadalci. Z več kot 18 leti izkušenj v kibernetski varnosti.

Vse objave

Komentarji

Ni še komentarjev. Bodite prvi!

Dodaj komentar

Vam je bil članek všeč?

Prijavite se na newsletter za mesečne varnostne vpoglede.

Prijavite se