4

The Twilio documentation includes detailed instructions for verifying that requests are actually coming from Twilio, based on a process for building and validating an HMAC-SHA1 hash:

...Compare your hash to ours, submitted in the X-Twilio-Signature header. If they match, then you're good to go.

They also say that:

All of the official Twilio Helper Libraries ship with a Utilities class which facilitates request validation. Head over to the libraries page to download the library for your language of choice.

... but I can't find that utility in the twilio-salesforce helper library. Can you help? Do you know of an implementation of this algorithm in Apex?

3

This is the official method to validate the x-twilio-signature. This method need to be implemented to the url (Salesforce site rest resource apex class) on which Twilio sends request to check if the request is actually from Twilio server.

    public boolean validateRequest(String expectedSignature, String url, Map<String,String> params) 
    {
               try 
               {
                     // sort the params alphabetically, and append the key and value of each to the url
                    String data = url;        
                    if(params!=null)
                    {
                        List<String> sortedKeys = new List<String>(params.keySet());
                        sortedKeys.sort();

                        for (String s: sortedKeys) {
                            data += s;
                            String v='';
                            if (params.get(s)!=null)
                                v=params.get(s);
                            data += v;
                        }
                    }

                    //compute the hmac on input data bytes, with AuthToken as key
                    Blob mac = Crypto.generateMac('hmacSHA1', Blob.valueOf(data), Blob.valueOf(authToken));

                    //base64-encode the hmac
                    String signature = EncodingUtil.base64Encode(mac);

                    return signature.equals(expectedSignature);
               } 
               catch (Exception e)
               {
                    return false;
               }
}

This is how Twilio created signature at server side:

  • Turn on SSL on your server and configure your Twilio account to use HTTPS urls.
  • Twilio assembles its request to your application, including the final URL and any POST fields (if the request is a POST).
  • If your request is a POST, Twilio takes all the POST fields, sorts them by alphabetically by their name, and concatenates the parameter name and value to the end of the URL (with no delimiter).
  • Twilio takes the resulting string (the full URL with query string and all POST parameters) and signs it using HMAC-SHA1 and your AuthToken as the key.
  • Twilio sends this signature in an HTTP header called X-Twilio-Signature

This is how it can be validate on our end:

  • Take the full URL of the request URL you specify for your phone number or app, from the protocol (https...) through the end of the query string (everything after the ?).
  • If the request is a POST, sort all of the POST parameters alphabetically (using Unix-style case-sensitive sorting order).
  • Iterate through the sorted list of POST parameters, and append the variable name and value (with no delimiters) to the end of the URL string.
  • Sign the resulting string with HMAC-SHA1 using your AuthToken as the key (remember, your AuthToken's case matters!).
  • Base64 encode the resulting hash value. Compare your hash to ours, submitted in the X-Twilio-Signature header. If they match, then you're good to go.

Note: Referenced from Twilio official documentation. Method is there already, in classes/TwilioRestClient.cls

|improve this answer|||||
  • Do you want to submit it as a contribution to the twilio library so others can benefit as well? github.com/twilio/twilio-salesforce/tree/master/src – Benj Oct 24 '13 at 20:13
  • OK - I just noticed it's there already, in classes/TwilioRestClient.cls This detail is great, but it would have been enough to point me over there. – Benj Oct 24 '13 at 20:15
  • Yes, Its already added. – Ashwani Oct 25 '13 at 5:40
1

I think that is already in the twilio library - I have a SFDC/Twilio integration that uses that.

My github repo is here, which uses a slimmed down Twilio library just to support SMS https://github.com/britishboyindc/TextToCase_Twilio_Salesforce

And here's the REST class that receives the Twilio message and checks the signature: https://github.com/britishboyindc/TextToCase_Twilio_Salesforce/blob/master/src/classes/smsToApex.cls

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.