The webhook security is pretty good but I noticed that it could be better in preventing replay attacks.
Anyone who is sniffing traffic can intercept the request and replay it. Granted someone can resolve this by storing processed webhook event ids but this requires the consumer to have a database set up to do this.
To get around this, it would be nice if hubspot added a timestamp for when the webhook was generated. These are added to the header.
X-HubSpot-Signature: timestamp=1492774577, signature=signature
Side note: Stripe does this and just abbreviates the keys (timestamp, signature) to keep the payload size small.
Now, one can reject the webhook if the timestamp is outside an acceptable threshold (say the last minute).
But what if the attacker just bumps up the timestamp something very recent (say 5 seconds ago)?
The timestamp can be included as a way of computing the signature:
timestamp + client secret + request body
Now if you try to just change the timestamp, the signature verification will fail because it's not valid.