Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP Twilio RequestValidator returning false on all endpoints

So I really don't know what the problem is here, I've tried many things, but I can't get the Twilio request hashes to match up. Let me explain.

I decided to implement an instance of Twilio's RequestValidator to ensure the requests were coming from Twilio. But after following the tutorial here: https://www.twilio.com/docs/usage/security?code-sample=code-validate-signature-of-request-1&code-language=PHP&code-sdk-version=5.x

The validator is only returning false. Here is the code that I used:

$url = 'https://example.com/api/endpoint/to/endpoint/';
$request_params = $_REQUEST;
$twilio_validator = new RequestValidator('myauthtoken');
if (!$twilio_validator->validate($_SERVER['HTTP_X_TWILIO_SIGNATURE'], $url, $request_params)) {
    throw new CallException('Not from Twilio');
}

Even though the URL is an example, that is exactly how I have the actual URL formatted...no port, basic auth, or fragment. Just the protocol, domain, and path with a trailing "/". In addition, the URL is the exact VoiceURL I set when I set up this Twilio App (this is calling the VoiceURL to one of my Twilio Apps).

My auth token is the auth token for my whole account

The request params is where I'm sure I'm messing something up. Twilio is making a GET request to this endpoint, and I tried using the $_GET superglobal as well, to no avail. I'm using $_REQUEST here because of this issue: https://github.com/twilio/twilio-php/issues/510 and because I thought it would be the best choice. I have also tried using file_get_contents('php://input') to the exact same problem (the hashes not matching, ultimately).

I even forked and opened a PR on the PHP SDK to update the class a little bit, just to see if I could learn any more...so I know the class and it's methods pretty well...I just don't see my issue.

What am I doing wrong here to make it so that the RequestValidator isn't validating that the requests from Twilio are coming from Twilio?

like image 623
Adam McGurk Avatar asked Nov 06 '22 15:11

Adam McGurk


1 Answers

So after a lot of research and working with Twilio help, I figured out the answer to my question.

When Twilio is making a GET request to my server, you aren't supposed to pass the GET parameters as the third parameter to the validate method on the RequestValidator class. When Twilio is making a GET request to your server, validating actually needs to look like this:

// this is the interesting part...you don't even set the pathname on the domain... 
// EVEN IF YOU THE PATHNAME IS SET IN YOUR VOICE URL. 
// This is because of the different way the RequestValidator handles GET and POST params
$domain = 'https://example.com'; // make sure to add no trailing '/'

// setting up the RequestValidator
$twilio_validator = new RequestValidator('myauthtoken');

// figuring out if the request is from twilio
$is_from_twilio = $twilio_validator->validate(

    // the signature header that Twilio sends
    $_SERVER['HTTP_X_TWILIO_SIGNATURE'], 

    // The domain name CONCATENATED to the Request URI. $_SERVER['REQUEST_URI'] holds everything that comes after the domain name in a URL (pathname, query parameters, and fragment)
    $domain.$_SERVER['REQUEST_URI']

    // if the request is a get request, as mine are, there is no need for the third parameter

);

// resolving the response
if (!$is_from_twilio) {
    echo 'Not from Twilio';
    exit;
}

Refer to the comments in the code for a more in depth discussion on the code at work here..

like image 164
Adam McGurk Avatar answered Nov 15 '22 04:11

Adam McGurk