PHP
Secure Webhook Signature Verification in PHP
Implement robust webhook signature verification in PHP to ensure the authenticity and integrity of incoming API payloads, protecting your application from forged requests.
<?php
/**
* Verifies the signature of an incoming webhook payload.
* This example assumes an HMAC-SHA256 signature provided in a header.
*
* @param string $payload The raw request body from the webhook.
* @param string $secret The shared secret key provided by the webhook sender.
* @param string $signatureHeader The value of the signature header (e.g., 'X-Hub-Signature-256').
* @param string $algo The hashing algorithm to use (e.g., 'sha256', 'sha1').
* @return bool True if the signature is valid, false otherwise.
*/
function verifyWebhookSignature(string $payload, string $secret, string $signatureHeader, string $algo = 'sha256'): bool
{
// 1. Extract the expected signature from the header
// Some services prefix with 'sha256=', others just provide the hash.
// Adjust this parsing based on the specific service.
if (strpos($signatureHeader, $algo . '=') === 0) {
$expectedSignature = substr($signatureHeader, strlen($algo . '='));
} else {
$expectedSignature = $signatureHeader;
}
// 2. Compute the HMAC signature of the payload using the shared secret
$computedSignature = hash_hmac($algo, $payload, $secret);
// 3. Compare the computed signature with the expected signature
// Use hash_equals() for constant-time comparison to prevent timing attacks.
return hash_equals($expectedSignature, $computedSignature);
}
// --- Example Usage ---
// In a real scenario, $payload would come from file_get_contents('php://input')
// and $signatureHeader from $_SERVER or getallheaders().
// The secret should be securely stored (e.g., environment variable).
// $webhookSecret = getenv('WEBHOOK_SECRET') ?: 'your-very-secret-key';
// $receivedPayload = file_get_contents('php://input');
// $receivedSignatureHeader = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? ''; // Adjust header name
// if (verifyWebhookSignature($receivedPayload, $webhookSecret, $receivedSignatureHeader)) {
// // Signature is valid, process the webhook data
// $data = json_decode($receivedPayload, true);
// // ... process data ...
// http_response_code(200);
// echo json_encode(['status' => 'success', 'message' => 'Webhook received and processed.']);
// } else {
// // Signature is invalid, reject the request
// error_log('Invalid webhook signature received!');
// http_response_code(403); // Forbidden
// echo json_encode(['status' => 'error', 'message' => 'Invalid signature.']);
// }
?>
How it works: This PHP snippet provides a function to securely verify webhook signatures. It takes the raw request body, a shared secret key, and the signature provided in the webhook header. It computes an HMAC signature of the payload using the secret and compares it against the received signature using `hash_equals()` to prevent timing attacks, ensuring the authenticity and integrity of webhook requests and protecting your application from forged data.