I'm trying to set up an automatic deployment when a pull request is merged into the main branch using Bitbucket webhooks.
However, I'm facing an issue with validating the webhook signature using the secret key.
What I Have
My secret key: q3bn5JCdR1yqK46V. (Already changed before posting this)
The webhook triggers correctly and sends the following headers:
X-Hub-Signature: sha256=51ff4d1fe17b05bc6c649abf4bb09e0f3d8d90d45faa43abcf66822cb658ae57
X-Hub-Signature-256: sha256=51ff4d1fe17b05bc6c649abf4bb09e0f3d8d90d45faa43abcf66822cb658ae57
What I'm Doing
I assumed the X-Hub-Signature-256 is the HMAC-SHA256 hash of the payload using my secret key, so I'm trying to generate the same hash with:
$hash = 'sha256=' . hash_hmac('sha256', $payload, $secret);
However, the hash I generate does not match the one provided in the headers.
How can I validate the Bitbucket webhook secret key using the content sent in the request?
This is what I am using for Github actions.
Note, to compare the hashes via hash_equals function!
Also note, the header keys are underscored in the $_SERVER globals array. The dashes are transformed by PHP.
In addition to the elements listed below, PHP will create additional elements with values from request headers. These entries will be named HTTP_ followed by the header name, capitalized and with underscores instead of hyphens. For example, the Accept-Language header would be available as $_SERVER['HTTP_ACCEPT_LANGUAGE'].
$body = file_get_contents(filename: 'php://input');
$signature = $_SERVER['HTTP_X_HUB_SIGNATURE_256'] ?? '';
$expected = 'sha256=' . hash_hmac(algo: 'sha256', data: $body, key: $secret);
if (hash_equals($signature, $expected)) {
return true;
}