Verifying a webhook

If you have created your webhook subscription using a signingKey you can validate the authenticity of the webhook by validating the request signature sent in the request header.

From the incoming webhook, parse the following request headers:

messagebird-signature

messagebird-request-timestamp

In addition, parse the request URL and the request Body.

To calculate the request signature:

  1. Base64 decode the messagebird-signature header;

  2. Create a SHA256 hash checksum of the request body as a binary result;

  3. Join the request timestamp (messagebird-request-timestamp header) with the request URL and request body checksum computed in step 2, separated by a new line (\n);

  4. Calculate HMACSHA256 using the signing key as the secret and the joined payload from step 3 to calculate the signature;

  5. Compare the output of step 4 to the signature from step 1;

Examples

The code examples below are pseudo code to help explain what needs to happen. We advise you to amend the example of your preferred language to what suits your codebase or framework.

<?php

function verifyWebhookSignature(
    string $headerSignature,
    string $headerTimestamp,
    string $receivedBody,
    string $requestedUrl,
    string $signingKey
): bool {
    $receivedDecodedSignature = base64_decode($headerSignature);

    $bodyHash = hash('sha256', $receivedBody, true);
    $computedSignature = hash_hmac(
        'sha256',
        sprintf("%s\n%s\n%s", $headerTimestamp, $requestedUrl, $bodyHash),
        $signingKey,
        true
    );

    return hash_equals($computedSignature, $receivedDecodedSignature);
}

// Example usage
$isVerified = verifyWebhookSignature(
    $_SERVER['HTTP_MESSAGEBIRD_SIGNATURE'],
    $_SERVER['HTTP_MESSAGEBIRD_REQUEST_TIMESTAMP'],
    file_get_contents('php://input'),
    'https://domain.com/webhook/bird',
    'secureSigningKey'
);

Last updated