日本語消えたスライド
TRANSCRIPT
https://github.com/shin1x1/twilio-api-security-demo
(c) 2016 Masashi Shinbara @shin1x1
電話番号が送られる
図図 - twilio
図図 - twilio
HTTPリクエストFrom: 090-xxxx-xxxx (発信元電話番号)
(c) 2016 Masashi Shinbara @shin1x1
情報をTwiMLで返す
図図 - twilio
図図 - twilio
TwiML(XML)を返す
<?xml version="1.0" encoding="UTF-8"?> <Response> <Say voice="woman" language="ja-JP"> 鈴木さんのポイントは 50 ポイントです。 </Say> </Response>
(c) 2016 Masashi Shinbara @shin1x1
偽装リクエスト図図 - twilio
図図 - twilio
Twilio Webサーバ会員
$ curl -d "From=%2B819012345678" https://example.com/api/calling
<?xml version="1.0" encoding="UTF-8"?> <Response> <Say voice="woman" language="ja-JP"> 田中さんのポイントは 100 ポイントです。 </Say> </Response>
(c) 2016 Masashi Shinbara @shin1x1
2. 通信元を制限
• HTTP Basic認証 / Digest認証 • ユーザ、パスワードを URL に含める • https://user:[email protected]/
(c) 2016 Masashi Shinbara @shin1x1
IPアドレスによる制限は?
https://www.twilio.com/help/faq/twilio-basics/which-ip-addresses-will-twilios-requests-come-from
• Twilio の送信元 IP アドレスは非公開 • 代わりにリクエストの検証を行う • どうしても必要なら相談
(c) 2016 Masashi Shinbara @shin1x1
3. リクエストの検証
・Twilio からのリクエストであることを確認
• 妥当であれば処理を実行 • そうでなければ処理を中断(エラー)
(c) 2016 Masashi Shinbara @shin1x1
HMAC-SHA1署名による検証
・ X-Twilio-Signatureヘッダ
• 所定のアルゴリズムで署名を算出 • 上記、2つを比較して合致すれば ok
署名算出
・URL - https://example.com/calling ・POSTパラメータ(キーでソート) Key2=value2 Key1=value1 From=+819012345678
https://example.com/calling From+819012345678Key1value1Key2value2
署名算出
・AuthTokenをキーにして、HMAC-SHA1署名 ・base64でエンコード
+sndfa0paQ+m2P0PZ4U/2lnLkHw=
https://example.com/callingKey1value1Key2value2From+819012345678
署名が一致するか
生成した署名 +sndfa0paQ+m2P0PZ4U/2lnLkHw=
X-Twilio-Signature: +sndfa0paQ+m2P0PZ4U/2lnLkHw=
合致するので、Twilioからのリクエストとみなす
twilio/sdk による検証
$validator = new Services_Twilio_RequestValidator($authToken); // ヘッダから署名取得 $signature = $request->header('X-Twilio-Signature'); // URL 取得 Request::setTrustedProxies([$request->getClientIp()]);$url = $request->getUri();// POST パラメータ取得 $postParameters = $request->input();// 署名検証 if (!$validator->validate($signature, $url, $postParameters)) { // OK} else { // NG}