Webhooks carry a certain level of security risk, as malicious actors can attempt to send fake webhooks, posing as legitimate services. This can lead to security vulnerabilities and other application issues.
To ensure the authenticity of received events from Yoco, the following two actions are required:
- Avoiding replay attacks
- Validating the signature
Avoiding replay attacks
Inside the webhook header there is an additional field
webhook-timestamp to indicate the Unix timestamp of when the webhook was signed.
Use this timestamp to drastically reduce the chance of a replay attack.
Because the timestamp is included in the header, the same header cannot be sent with a different timestamp without causing an invalid signature. When verifying the signature, you should also validate that the timestamp is within an acceptable threshold from your current system time (in Unix epoch format).
We recommend a threshold of up to 3 minutes. If Yoco retries sending the webhook notification event, the timestamp at the time of sending the retried event is used, so each attempt would have a new timestamp and therefore a new hash.
Validating the signature
Events sent from our service contain the
To ensure the webhook's authenticity and confirm its origin from our service, follow the provided steps to compare a generated signature with the signature from the header.
1. Construct the signed content
To generate the signed content, concatenate the values of the
webhook-timestamp header, and the raw request body using a full stop character as a separator.
Make sure to use the raw request body in this step. Any minor modification to the body will generate a completely different signature.
2. Determine the expected signature
To calculate the expected signature, use the secret key and the signed content to generate a
Then, encode this value using
Before calculating the expected signature, ensure that you exclude the whsec_ prefix from the secret key.
3. Compare signatures
webhook-signature header consists of a list of signatures and their version identifiers, separated by spaces.
Typically, the signature list consists of only one element, but it can contain any number of signatures.
Before verifying the signature, make sure to remove the version prefix and delimiter (e.g., v1,).
The generated signature should be compared with the signature sent in the
If the generated signature matches the provided signature, you can proceed with processing the webhook event.
When comparing the signatures, it is recommended to use a constant-time string comparison method to prevent timing attacks.