動画

F8 2015以降、Jonathan Gross氏とBrent Dorman氏によって、Facebookログインを統合する際のセキュリティを増強する方法が調査されています。

セキュリティのチェックリスト

Facebookログインを使用するすべてのアプリでは、少なくとも次のリストの内容を必ず実装する必要があります。これ以外にアプリに独自の機能がある場合は、最大限の安全性を確保するための手段を検討する必要があります。セキュリティ保護されていないアプリは、利用者からの信頼を失い、使用されなくなってしまいます。

クライアント側やデコンパイル可能なコードにはApp Secretを含めない

サーバー間のGraph API呼び出しにはすべてApp Secretで署名する

クライアントでは固有の短期トークンを使用する

アプリで使用しているアクセストークンが、実際にアプリによって生成されたトークンであると信頼しない

ログインダイアログを使用する際には、状態パラメーターを使用する

可能であれば、公式のFacebook SDKを使用する

Facebookアプリ設定をロックダウンし、アプリの攻撃対象になる領域を狭める

HTTPSを使用する

App Secret

App Secretは、一部のログインフローでアクセストークンを生成するために使用されます。App Secret自体は、信頼されている利用者のみに使用を限定して、アプリの使用を保護することを目的としています。App Secretを使用するとアプリアクセストークンを簡単に作成できます。このトークンはアプリの利用者に代わってAPIリクエストを行うため、App Secretが外部から不正アクセスされないようにすることが極めて重要です。

このため、アプリの開発者以外の利用者がアクセスできるコードにApp Secretやアプリアクセストークンを含めないようにしてください。このルールは、クライアント側コード(HTMLやJavaScriptなど)やネイティブアプリ(iOS、Android、Windowsデスクトップアプリなど)といった、セキュリティで保護されていないコードを使用するすべてのメソッドに当てはまります。

最適なセキュリティ保護を提供するには、アプリアクセストークンの使用をアプリのサーバー側に限定することをおすすめします。ネイティブアプリの場合は、アプリは独自サーバーとやり取りを行い、サーバーがアプリアクセストークンを使用してFacebookにAPIをリクエストするように設定することをおすすめします。以上の理由から、アプリダッシュボードの詳細設定にある「アプリタイプ」がNative/Desktopに設定されている場合は、App Secretやアプリアクセストークンがネイティブアプリのバイナリに含まれていると想定され、アプリアクセストークンで署名された呼び出しは処理できなくなります。APIの動作は、アクセストークンが提供されていない場合の動作となります。

App Secretが不正アクセスされてしまった場合は、アプリダッシュボードの基本設定から直ちにリセットする必要があります。リセットプロセスの開始時には、不正アクセスされたapp secretを引き続き使用してリクエストを実行できる時間数を指定できます。ただし、Facebookからの送信(署名されたリクエストなど)には直ちに新しいapp secretが使用されるため、できるだけ早急に新しいapp secretに合わせてコードを調整する必要があります。

appsecret_proofでセキュリティ保護されたサーバー側の呼び出し

FacebookのAPIへのサーバー間の呼び出しにappsecret_proofパラメーターの署名を求めるようにすると、マルウェアやスパム送信者にさらされる部分を狭めることができます。 このトピックについて詳しくは「Securing Graph API Calls (Graph API呼び出しのセキュリティ保護)」をご覧ください。

短期トークンとコードフローでセキュリティ保護されたクライアント側の呼び出し

構成によっては、複数のクライアント間で長期トークンを再利用しますが、 このような設定は使用しないでください。 代わりに、コードフローで生成される短期トークンを使用してください(アクセストークンに関するドキュメントをご覧ください)。

トークンのハイジャック

トークンがハイジャックされる仕組みを理解するため、あるネイティブiOSアプリがAPI呼び出しを直接実行するのではなく、そのアプリが所有するサーバーとやり取りをし、iOS SDKを使用して生成されるトークンをサーバーに渡す、という例を使用して説明していきます。サーバーはそのトークンを使用してAPI呼び出しを行います。

サーバーがトークンの受け取りに使用するエンドポイントは外部から不正アクセスされる危険性があり、第三者によってアクセストークンがまったく別のアプリに渡されてしまうことも考えられます。これは明らかにセキュリティ面で問題がありますが、アクセストークンが、そのトークンを使用するアプリから来たものと仮定せず、デバッグのためのエンドポイントを使用してチェックを行うようにすることによって対処できます。

状態パラメーター

ウェブサイトでFacebookログインダイアログを使用している場合、stateパラメーターは、アプリをクロスサイトリクエストフォージェリ攻撃から守る固有の文字列になります。

制限モードの有効化

制限モードでは、リダイレクトのハイジャックを防ぎ、アプリを安全に保つことができます。制限モードの有効化は、現在のところInstagram APIで必要ですが、まもなくすべてのアプリで必要になります。

アプリダッシュボードで制限モードを有効にする前に、Facebookログインの設定で次の操作を行って、現在のリダイレクトトラフィックが引き続き機能していることを確認します。

  • ダイナミックリダイレクトURIを使用するアプリでは、ステートパラメーター を使用してダイナミック情報を一部のリダイレクトURIにのみ返すようにします。次に、制限されたリダイレクトURIを有効なOAuthリダイレクトURIリストに追加します。

  • 一部のリダイレクトURIのみを使用するアプリでは、それぞれのURIを有効なOAuthリダイレクトURIリストに追加します。

  • Facebook SDKのみを使用するアプリでは、リダイレクトトラフィックはすでに保護されています。追加の操作は必要ありません。

これらの操作の後には、制限モードを必ず有効にしてください。

制限モードのしくみ

制限モードでは、有効なOAuthリダイレクトURIリストとの完全一致を条件にすることによって、リダイレクトURIのハイジャックを防ぎます。たとえば、リストにwww.example.comが含まれている場合、制限モードではwww.example.com/tokenは許可されません。有効なOAuthリダイレクトURIリストに存在しない余分なクエリパラメーターを含めることもできません。

Facebookアプリ設定のロックダウン

アプリで使用していない認証フローをすべて有効また無効にして、攻撃対象となる領域を最小化します。

  • クライアントでは、クライアント生成のトークンやサーバー提供の長期トークンではなく、コード生成された短期アクセストークンを使用します。 コード生成された短期アクセストークンフローの場合、アプリサーバー側でコードをトークンと交換する必要があります。これにより、ブラウザーでトークンを取得する方法よりもセキュリティが向上します。アプリのセキュリティを高めるには、可能な限りこのフローを使用するようにします。アプリでこのフローを有効にしておくだけで、利用者のコンピュータ上で実行されるマルウェアはアクセストークンを取得して不正な操作を実行できなくなります。 詳しくは、アクセストークンに関するドキュメントをご覧ください。

  • アプリで使用していなければ、クライアントOAuthログインを無効にします。 クライアントOAuthログインは、OAuthクライアントトークンフローを使用するための一般的なオン/オフスイッチです。 FacebookログインSDKなど、アプリでクライアントOAuthフローを使用していないのであれば、このフローを無効にします。ただし、クライアントOAuthログインを無効にしている場合は、アクセストークンのアクセス許可をリクエストできません。この設定は、アプリダッシュボードの[製品] > [Facebookログイン] > [設定]セクションにあります。

  • ウェブOAuthフローを無効にするか、リダイレクトホワイトリストを指定します。 [ウェブOAuthログイン]設定により、Facebookウェブログインダイアログを使用して個別のウェブサイトにトークンを返す、OAuthクライアントトークンが有効になります。この設定は、アプリダッシュボードの[製品] > [Facebookログイン] > [設定]セクションにあります。カスタムのウェブログインフローを作成しない場合や、FacebookログインSDKをウェブで使用しない場合は、この設定を無効にします。
  • HTTPSを使用します。この設定では、JavaScript SDKを使用してアクセストークンを取得するOAuthリダイレクトとページに、HTTPSを要求します。2018年3月以降に作成されたすべての新しいアプリには、デフォルトでこの設定が適用されます。既存のアプリでも、HTTPSのみを使用するよう2019年3月までに移行を完了させてください。ほとんどの主要クラウドアプリホストでは、アプリ用TLS証明書の自動設定が無料で提供されています。アプリを自己ホストしている場合、または利用しているホスティングサービスがデフォルトでHTTPSを提供していない場合は、Let's Encryptからドメイン用の証明書を無料で入手できます。
  • アプリで使用していなければ、埋め込みブラウザーOAuthフローを無効にします。 一部のデスクトップ版とモバイル版のネイティブアプリでは、埋め込みウェブビュー内でOAuthクライアントフローを実行して利用者の認証を行います。アプリでこの認証を行わない場合は、アプリダッシュボードの[製品] > [Facebookログイン] > [設定]セクションでこの設定を無効にします。
  • アプリで使用しなければ、モバイルシングルサインオンフローを無効にします。 アプリでiOSログインやAndroidログインを使用しない場合、[設定] > [基本]の、[iOS]と[Android]セクションで「シングルサインオン」の設定を無効にします。

アプリダッシュボードには、セキュリティ問題につながる恐れのある攻撃対象の領域をなくすために次のような追加の設定があります。

  • [基本] > [App Secret]。app secretが不正アクセスされた場合は、ここでリセットできます。
  • [基本] > [アプリドメイン]。アプリに代わってFacebookログインを実行する際に使用されるドメインとサブドメインをロックダウンするにはこの設定を使用します。
  • [詳細] > [アプリタイプ]。モバイルまたはデスクトップ向けのネイティブアプリを作成してapp secretを含める場合は、この設定をNative/Desktopに設定します。そうすることでデコンパイルやapp secretの盗難からアプリを保護します。
  • [詳細] > [サーバーIPホワイトリスト]。app secretを使用したGraph API呼び出しの実行元IPアドレスのリストを指定します。 この範囲外のIPアドレスから実行すると、app secretを使用したGraph API呼び出しが失敗します。 ユーザーアクセストークンを使用した呼び出しはこの設定の影響を受けません。
  • [詳細] > [IPホワイトリストの設定を更新]。第三者によってこれらのアプリ設定が特定の範囲に変更されないように、IPアドレスをロックダウンします。施設内ブロードバンドのIPホワイトリストを設定します。IPアドレスが変わると、アプリ設定を編集できなくなります。
  • [詳細] > [通知メールを更新]。アプリダッシュボードで設定が変更された場合に、メールアドレス宛に通知を送信します。
  • [詳細] > [ストリーム投稿のURLセキュリティ]。アプリが所有するドメインを指定していないURLの公開を停止します。アプリが他のサイトへのリンクを公開する場合など、状況によっては不要となります。

HTTPSの使用

インターネットプロトコルには、HTTPではなく、暗号化できるHTTPSを使用します。HTTPSでは、送信されるデータが非公開になり、盗聴攻撃を防ぐことができます。また、広告の導入や悪意のあるコードによって、転送中にデータが改ざんされるのを防ぎます。