This would have saved customers at a previous company of mine weeks of developer time, thank you!
Can you include a mention of the signing key algorithm (ed25519) higher up in the README? That was important information I had to scroll a long ways to find.
> One thing worth calling out: asymmetric signatures alone don't protect against replay attacks. Unless the signed payload includes a timestamp or nonce, an attacker can just re-deliver a captured webhook verbatim and it will verify fine. HMAC-based schemes like Stripe's include the timestamp in the signed payload for exactly this reason. So any spec built on these libraries should probably make the timestamp part of the signed message rather than leaving replay protection entirely up to the consumer.
I can't respond to this comment directly because it is dead, but that is an important thing to call out. We have replay protection built into the libraries. The signature contains a timestamp, a unique webhook id for the event, the recipient id, and the target endpoint’s url and method.
The verify function returns an error if the timestamp is expired or if the recipient id or target url are not as expected. The timestamp check is standard for any type of signature. The recipient id and target url check is unique to asymmetric signatures and prevents a situation where one user can forward their requests or trick the webhook producer into sending requests to a different user.
If extra protection is desired, the webhook id is returned to the consumer after they verify the request and can be used to guarantee that a webhook can only be received once (eg. throw the webhook ids in redis with a ttl longer than the signature ttl and reject any requests with webhook ids that have already been seen).
This would have saved customers at a previous company of mine weeks of developer time, thank you!
Can you include a mention of the signing key algorithm (ed25519) higher up in the README? That was important information I had to scroll a long ways to find.
That's good to hear! And yep. I added it at the top.
A set of cross-language libraries that perform asymmetric signing, verification, and key management for webhook authentication.
Correct Hooks makes one of the most secure authentication mechanisms for webhooks the easiest to implement for both webhook producers and consumers.
Yep! That's it
> One thing worth calling out: asymmetric signatures alone don't protect against replay attacks. Unless the signed payload includes a timestamp or nonce, an attacker can just re-deliver a captured webhook verbatim and it will verify fine. HMAC-based schemes like Stripe's include the timestamp in the signed payload for exactly this reason. So any spec built on these libraries should probably make the timestamp part of the signed message rather than leaving replay protection entirely up to the consumer.
I can't respond to this comment directly because it is dead, but that is an important thing to call out. We have replay protection built into the libraries. The signature contains a timestamp, a unique webhook id for the event, the recipient id, and the target endpoint’s url and method.
The verify function returns an error if the timestamp is expired or if the recipient id or target url are not as expected. The timestamp check is standard for any type of signature. The recipient id and target url check is unique to asymmetric signatures and prevents a situation where one user can forward their requests or trick the webhook producer into sending requests to a different user.
If extra protection is desired, the webhook id is returned to the consumer after they verify the request and can be used to guarantee that a webhook can only be received once (eg. throw the webhook ids in redis with a ttl longer than the signature ttl and reject any requests with webhook ids that have already been seen).
[flagged]