Security and Validation
Webhook Signature Verification Guide
Webhook endpoints are public HTTP routes. Without verification, anyone on the internet could send requests that look like legitimate events. Signature verification ensures the request actually came from the provider.
Most webhook providers sign each request using a shared secret. The receiving server recomputes the signature using the raw request payload and compares it with the value sent by the provider.
If the signatures match, the request can be trusted.
How webhook signatures work
Providers typically generate an HMAC hash using the request body and a secret key.
signature = HMAC_SHA256(payload, secret)
The resulting value is placed in a request header.
Your server recomputes the hash and compares the values.
Laravel verification example
$payload = request()->getContent();
$expected = hash_hmac('sha256', $payload, $secret);
if (!hash_equals($expected, $signature)) {
abort(400);
}
Using
hash_equals()prevents timing attacks when comparing values.
Common implementation mistakes
- Parsing JSON before computing the signature
- Ignoring timestamp validation
- Using simple string comparison
- Logging sensitive payloads
Signature verification must always use the raw request body exactly as it was received.
Why verification matters
Without verification, malicious actors could send forged webhook events such as fake payment confirmations or account upgrades.
For systems that automate billing or access control, that risk is serious.
If you are debugging webhook request failures, see our guide on debugging webhook failures in production.