Unable to Validate Signature Header for Incoming Requests on Webhooks

webhooks

#1

I’ve been trying to implement the “Validating the Signature Header” part of securing the webhook but I haven’t been able to correctly figure out the implementation logic.

This is an excerpt from the page on how to correctly validate incoming requests;

  1. Create a hash using your consumer secret and incoming payload body.
  2. Compare created hash with the base64 encoded x-twitter-webhooks-signature value. Use a method like compare_digest to reduce the vulnerability to timing attacks.

I have created the HMAC hash as described (payload as message and consumer key as secret) but I’m not so clear on the second step. I have tried base64 encoding the entire x-twitter-webhooks-signature header value that is, sha256=HASH_STRING but when I compare the hashes it doesn’t evaluate to true.

Here’s my code for context;

        //fetch header value
        $signature = $request->header('x-twitter-webhooks-signature');
        //split signature to get hash algorithm used
        $signatureSplit = explode('=', $signature);
        $hashAlgo = $signatureSplit[0];
        
        if ($hashAlgo == 'sha256') {
            $payload = $request->getContent();
            $twitterSecret = env("TWITTER_API_SECRET");
            
            $payloadHashDigest = hash_hmac('sha256', $payload, $twitterSecret);
            $encodedSignature = base64_encode($signature);
                        
            if (hash_equals($payloadHashDigest, $encodedSignature)) {
                return true;
            }else{
                return false;
            }
        }else{
            return false;
        }

It would also be really helpful if the portion of the docs in question has sample code that demonstrates the behavior.

I’ll appreciate any help I can get.
Thank you.


#2

Hi @reszr, here is some PHP code for generating the string to compare. This was provided by one of partners. It is for the challenge response, but the approach should be similar. Just using the request body instead of the token.

We’re reworking much of the documentation now, so we’ll add a code sample for this section. Thanks for the feedback.