Feel free to use SSL to protect communications between Twilio and your web application. Just specify an HTTPS url. Note: Twilio cannot currently handle self signed certificates.
Twilio supports HTTP Basic and Digest Authentication. This allows you to password protect your TwiML URLs on your web server so that only you and Twilio can access them. You may provide a username and password via the following URL format.
https://username:password@www.myserver.com/my_secure_document
Twilio will authenticate to your web server using the provided username and password and will remain logged in for the duration of the call. We highly recommend that you use HTTP Authentication in conjunction with SSL. For more information on Basic and Digest Authentication, refer to your web server documentation.
If you specify a password-protected URL, Twilio will first send a request with no Authorization header. After your server responds with a 401 Unauthorized response, Twilio will make the same request with an Authorization header.
If your application exposes sensitive data, or is possibly mutative to your data, then you may want to be sure that the HTTP requests to your web application are indeed coming from Twilio, and not a malicious third party. To allow you this level of security, Twilio cryptographically signs its requests. Here's how it works:
Then, on your end, if you want to verify the authenticity of the request, you can re-assemble the data string by going through the exact same process. If our two hashes match, then the request was authentic. You can then be sure that all the data used to construct the hash, including the full URL, query string and POST parameters were all sent to you by Twilio. Here's how you would perform the validation on your end:
Let's walk through an example request. Let's say Twilio made a POST to your page:
https://mycompany.com/myapp.php?foo=1&bar=2
And let's say Twilio posted some digits from a <Gather> to that url, in addition to all the usual POST fields
Create a string that is your URL with the full query string:
https://mycompany.com/myapp.php?foo=1&bar=2
Sort the list of POST variables by the parameter name (using Unix-style case-sensitive sorting order):
Append each POST variable, name and value, to the string with no delimiters:
https://mycompany.com/myapp.php?foo=1&bar=2CallSidCA1234567890ABCDECaller+14158675309Digits1234From+14158675309To+18005551212
Hash the resulting string using HMAC-SHA1, using your AuthToken as the key. Let's suppose your AuthToken is 12345. Then take the hash value returned from the following function call (or its equivalent in your language of choice):
hmac_sha1(https://mycompany.com/myapp.php?foo=1&bar=2CallSidCA1234567890ABCDECaller+14158675309Digits1234From+14158675309To+18005551212, 12345)
Now take the Base64 encoding of the hash value (so it's only ASCII characters):
RSOYDt4T1cUTdK1PDd93/VVr8B8=
Compare that to the hash Twilio sent in the X-Twilio-Signature HTTP header. Match them up!
Here are examples from our helper libraries:
<?php
// Your auth token from twilio.com/user/account
$authToken = '12345';
// Download the twilio-php library from twilio.com/docs/libraries, include it
// here
require('/path/to/twilio-php/Services/Twilio.php');
$validator = new Services_Twilio_RequestValidator($authToken);
// The Twilio request URL. You may be able to retrieve this from
// $_SERVER['SCRIPT_URI']
$url = 'https://mycompany.com/myapp.php?foo=1&bar=2';
// The post variables in the Twilio request. You may be able to use
// $postVars = $_POST
$postVars = array(
'CallSid' => 'CA1234567890ABCDE',
'Caller' => '+14158675309',
'Digits' => '1234',
'From' => '+14158675309',
'To' => '+18005551212'
);
// The X-Twilio-Signature header - in PHP this should be
// $_SERVER["HTTP_X_TWILIO_SIGNATURE"];
$signature = 'RSOYDt4T1cUTdK1PDd93/VVr8B8=';
if ($validator->validate($signature, $url, $postVars)) {
echo "Confirmed to have come from Twilio.";
} else {
echo "NOT VALID. It might have been spoofed!";
}
We highly recommend you use the helper libraries to do signature validation. If you are curious what the libraries are doing under the hood, here is an example written in PHP that you can copy:
<?php
// Your auth token from twilio.com/user/account
$authToken = '456bef';
public function computeSignature($url, $data = array()) {
// sort the array by keys
ksort($data);
// append the data array to the url string, with no delimiters
foreach ($data as $key => $value) {
$url = $url . $key . $value;
}
// This function calculates the HMAC hash of the data with the key
// passed in
// Note: hash_hmac requires PHP 5 >= 5.1.2 or PECL hash:1.1-1.5
// Or http://pear.php.net/package/Crypt_HMAC/
$hmac = hash_hmac("sha1", $url, $authToken, true)
return base64_encode($hmac);
}
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.
Please keep your AuthToken secure. It not only enables access to the REST API, but also to request signatures.