2023年5月1日を持ちまして、株式会社KDDIウェブコミュニケーションズのTwilioリセール事業が終了したため、本記事に記載されている内容は正確ではないことを予めご了承ください。
はじめに
Twilioには、サーバーレスアーキテクチャーである Twilio Functions というサービスがあります。この仕組を使うことで、ユーザ側にサーバーを用意せずに、動的なTwiMLを生成したり、TwilioのRestAPIで電話やSMSを操作することができます。
Functionsを実行するためには、Functionsを作成したときに自動的に生成されるURLを呼び出す必要があります。
この記事では、Functionsの呼び出し時のセキュリティ対策として、「ACCESS CONTROL」を活用する方法を記載します。
ACCESS CONTROLとは
Twilioには、Functionsに限らず、Twilioからの正式なリクエストであることを証明するために、バリデーションリクエストという仕組みが用意されています。具体的には、TwilioからのリクエストURLやパラメータに対して、ユーザしか知り得ないAuth Tokenでハッシュ値を取って、それをX-Twilio-SignatureというHTTPヘッダーオプションの入れています。
ユーザ側は、このヘッダー値を自ら検証することで、本当にTwilioからのリクエストであること、パラメータを含め改ざんがされていないことを保証することができます。
Twilio Functionsには、Functionsの生成時に以下のACCESS CONTROLオプションがあります。
このチェックボックスをONにすることで、上記のバリデーションリクエストがFunctions実行時に検証されます。
すなわち、Twilio内部からのアクセスに制限する場合(たとえば、電話番号の着信設定時のURLとしてFunctionsを指定する場合など)は、チェックをONにしておくことが推奨されます。
外部からのFunctions呼び出しでバリデーションリクエストを利用する
上記のように、X-Twilio-Signatureを検証するのが、ACCESS CONTROLの目的ですので、外部のサーバーからFunctionsをコールする場合も、Twilioからのリクエスト同様にX-Twilio-Signatureを生成してヘッダーに付与することで、ACCESS CONTROLをONにしながらセキュアなアクセスが可能となります。
X-Twilio-Signatureの生成例
以下のコードは、Node.jsを使って、X-Twilio-Signatureを生成するサンプルです。
// Get twilio-node from twilio.com/docs/libraries/node
const crypto = require('crypto');
// Your Auth Token from twilio.com/console
const authToken = 'YOUR_AUTH_TOKEN';
// FunctionsのURL
let url = '呼び出したいFunctionsのURL';
// POSTパラメータ
const params = {
test: 'hogehoge'
};
// パラメータを並び替えて、URLに連結した文字列を生成
Object.keys(params).sort().forEach(function(key) {
url = url + key + params[key];
});
// X-Twilio-Signatureの生成
const signature = crypto.createHmac('sha1', authToken).update(Buffer.from(url, 'utf-8')).digest('base64')
console.log(signature);
このようにして生成したX-Twilio-SignatureをFunctionsの呼び出し時にPOSTヘッダーに入れてあげることで、外部から呼び出す際のセキュリティ対策となります。ちなみにSignatureが違っている場合は、呼び出しが403エラーとなります。