0

When Twilio invokes a callback method to fetch the TwiML <Say> for Voice, I see that Twilio sets "x-twilio-signature" in the HTTP header.

I need to verify that the actual request came from Twilio.

I have a simple war file running on Tomcat and the app is built using Spring.

I did something like the following:

//Get the TwilioUtils object initialized
TwilioUtils twilioUtils = new TwilioUtils("******myAuthToken");

//Get the URL from HttpRequest
String url = httpRequest.getRequestURL().toString();
Map<String, String> allRequestParams = getAllRequestParams(httpRequest);
Map<String, String> headers = getAllRequestHeaders(httpRequest);

//Get the signature generated for the Url and request parameters 
//allRequestParams is a map of all request values posted to my service by Twilio
String validSig = twilioUtils.getValidationSignature(url, allRequestParams);

//Get the x-twilio-signature value from the http header map
String xTwilioSignature = headers.get("x-twilio-signature”);

//This is different from what I get below
logger.info("validSig = " + validSig);
logger.info("xTwilioSignature = " + xTwilioSignature );
//This is always false
logger.info("Signature matched : " +  twilioUtils.validateRequest(xTwilioSignature, url,
   allRequestParams));

I would like to know what am I doing wrong. Is my approach to validate "x-twilio-signature" incorrect?

If it is incorrect, what's the right way to do it?

I am using the helper library class TwilioUtils provided by Twilio to validate it.

All the time the signature from Twilio is different from what I get from the TwilioUtils object.

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
serverfaces
  • 1,155
  • 4
  • 22
  • 49

1 Answers1

0

Megan from Twilio here.

Are you following the steps suggested in the security documentation?

validateRequest expects three arguments. I believe you're missing the url there.

Consider this example:

public class TwilioUtilsExample {

    public static void main(String[] args) {

        // Account details
        String accountSid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        String authToken = "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY";

        //This is the signature we expect
        String expected_sig = "SSSSSSSSSSSSSSSSSSSSSSSSSSSS";

        //This is the url that twilio requested
        String url = "http://UUUUUUUUUUUUUUU";

        //These are the post params twilio sent in its request
        Map<String,String> params = new HashMap<String,String>();

        // Be sure to see the signing notes at twilio.com/docs/security
        TwilioUtils util = new TwilioUtils(authToken, accountSid);

        boolean result = util.validateRequest(expected_sig, url, params);

        if (result) {
            System.out.print( "The signature is valid!\n" );
        } else {
            System.out.print( "The signature was NOT VALID.  It might have been spoofed!\n" );
        }

    }

} 

Hope this is helpful!

Megan Speir
  • 3,745
  • 1
  • 15
  • 25
  • The form parameters returned by Twilio has both my query parameters and Twilio Post parameters. The URL (for TwilioUtils) needs to have all query params appended to it. Then for the map (params), I got to set only those fields that Twilio set. As the form has both query params and Twilio fields, first I got to extract my query params and append with the URL. Then I got to remove all my query params from the form fields and construct a map for it. Then it worked. – serverfaces Dec 05 '15 at 23:15
  • I use the same approach. It works for GET but always getting false for POST. – user1578872 Jul 02 '16 at 14:07