Facebook アプリで X-Frame-Options エラーが発生したときの対処法

Posted on

Facebook アプリを作ってるときに、iframe 内のアプリが真っ白になって何も表示されなくなる現象に出くわしました。毎回必ず起きるわけではなく、稀に起きるときがあるという感じです。

ひとつ確認できていたのは、真っ白になるときは必ず "X-Frame-Options: DENY" のレスポンスヘッダーが返ってくるということだけ。

X-Frame-Options は他サイトのフレームから自サイトが読み込まれるのを制御するレスポンスヘッダーです。 DENY が指定されていれば、他サイトのフレームから読み込まれることはありません。詳しくは MDN のサイトを参考にしてください。

結論から先に書くと、iframe 内から Facebook のログイン URL (Facebook::getLoginUrl で取得できる) にリダイレクトすることで発生していました。

このアプリは PHP で OAuth 認証を行い、Facebook のフレンド情報を取得しています。セッションが切れているとフレンド情報が取得できないため、定期的に /me/permissions を叩いてセッションが有効かどうかチェックしていました。この処理で例外が発生したらログイン URL にリダイレクトする処理を書いていましたが、これがまずかったようです。

try {
    // セッションチェックの処理
} catch (FacebookApiException $e) {
    // ログイン URL へリダイレクトする処理
}

Facebook アプリの設定画面で許可したドメイン以外の URL を呼び出すと、Facebook 側が X-Frame-Options を返して不正なアプリが実行されないようになっています。今回の場合、自分のアプリ用ドメインから www.facebook.com へリダイレクトされ、Facebook のログインページが呼び出されていたことになります。おそらく、アプリが乗っ取られた際の防御策だと思われます。

再現性がなく稀に起きていたのは、開発者は頻繁にアクセスするのでセッションが切れず、このバグを踏むことはなかったためです。