PHP
Secure Webhook Signature Verification
Implement robust PHP code to verify HMAC-SHA256 signatures for incoming webhooks, ensuring data integrity and preventing spoofed requests.
<?php
function verifyWebhookSignature(string $payload, string $signatureHeader, string $secret, string $algo = 'sha256'): bool
{
// Extract the signature from the header. Format might be 't=timestamp,v1=signature'
// For simplicity, let's assume the signature is directly the hex hash.
// Real-world APIs often prefix it (e.g., 'sha256=' or 'v1=')
// Adjust this parsing based on the specific API's documentation.
$providedSignature = str_replace(["sha256=", "v1=", "t="], "", $signatureHeader);
$providedSignature = trim($providedSignature);
if (empty($providedSignature)) {
return false; // No signature provided
}
// Calculate the expected signature
$expectedSignature = hash_hmac($algo, $payload, $secret);
// Use hash_equals for timing attack safe comparison
return hash_equals($expectedSignature, $providedSignature);
}
// Example Usage:
// $secret = 'YOUR_WEBHOOK_SECRET'; // This should be a strong, randomly generated string
// $payload = file_get_contents('php://input'); // The raw JSON payload from the request body
// $signatureHeader = $_SERVER['HTTP_X_HUB_SIGNATURE_256'] ?? ''; // e.g., for GitHub, or 'HTTP_X_STRIPE_SIGNATURE' for Stripe
// if (verifyWebhookSignature($payload, $signatureHeader, $secret)) {
// // Signature is valid, process the webhook event
// http_response_code(200);
// echo 'Webhook received and verified.';
// // file_put_contents('webhook.log', date('Y-m-d H:i:s') . ' - Valid webhook: ' . $payload . "
", FILE_APPEND);
// } else {
// // Signature is invalid or missing, reject the request
// http_response_code(403);
// echo 'Invalid webhook signature.';
// // file_put_contents('webhook_error.log', date('Y-m-d H:i:s') . ' - Invalid signature or missing: ' . $signatureHeader . ' with payload: ' . $payload . "
", FILE_APPEND);
// }
?>
How it works: This PHP snippet provides a `verifyWebhookSignature` function essential for securing webhook endpoints. It takes the raw request payload, the signature header (e.g., `X-Hub-Signature-256`), and your secret key to calculate an expected HMAC signature. By comparing this expected signature with the one provided in the header using `hash_equals` (which is resistant to timing attacks), you can confirm the webhook's authenticity and integrity, ensuring that the request truly came from the expected service and hasn't been tampered with.