2011年8月10日 #oauth #form #mixi #mixi #post #signature

現象

MixiモバイルアプリのフォームからPOSTするとOAuth Signatureが不一致で検証が通らない。

デバッグ

フォームをPOSTするときはフォーム内のデータがOAuthのBase StringのNormalize Request Parametersに含まれます。
これはOAuthに仕様に準じてます(http://oauth.net/core/1.0a/#anchor13)が、
なぜかMixiだと通れないです。

<form action="?guid=ON&url=http%3A%2F%2Fexample.com%2Ffoo%2F" method="post">
  <input name="field1" type="text" value="value1" />
  <input type="submit" value="送信" />
</form>

こんなフォームがあるとして、中のfield1がNormalize Request Parametersに存在するとダメだってことが検証でわかりました。

回避方法

フォームPOSTする箇所を特定して、その場合はOAuth Signatureを検証しないようにしました。

参考リンク

同じ現象にあった方がいました:

2011年5月20日 #php #facebook #oauth

Our automated systems have detected that you may be inadvertently allowing authentication data to be passed to 3rd parties.

ここ最近Facebookから”認証情報をサードパーティに渡している可能性がある、48時間内に修正しろ”みたいなメールが届いた人が多いと思います。
メール本文です:

Dear Developer of xxxxxx {your app name} xxxxx, Our automated systems have detected that you may be inadvertently allowing authentication data to be passed to 3rd parties. Allowing user ids and access tokens to be passed to 3rd parties, even inadvertently, could allow these 3rd parties to access the data the user made available to your site. This violates our policies and undermines user trust in your site and Facebook Platform. In every case that we have examined, this information is passed via the HTTP Referer Header by the user’s browser. This can happen when using our legacy authentication system and including <iframe>, <img> or <script> content from 3rd parties in the page that receives authentication data from Facebook. Our legacy mechanism passes authentication information in the URL query string which, if handled incorrectly, can be passed to 3rd parties by the browser. Our current OAuth 2.0 authentication system, released over a year ago, passes this information in the URL fragment, which is not passed to 3rd parties by the browser. Please ensure that you are not allowing this data to be passed immediately. Accessing your site as a test user while running a HTTP proxy/monitor like Charles or Fiddler is the best way to determine if you are allowing this information to be passed. If you discover the issue, you can do one of two things: 1. Migrate your site to use our OAuth 2.0 authentication system. We are requiring all apps and sites to update to this mechanism by Sept. 1, 2011. Migrating now will address this issue and ensure that you are one of the first to meet the deadline. For more details, please see our Authentication Guide. 2. Create and use an interstitial page to remove the authentication data before redirecting to your page with 3rd party content. This approach is used by many of our largest developers today (although they are all migrating to OAuth 2.0 shortly). This is a simple and straightforwardchange that should have minimal impact on your site. For more details on this approach, see our Legacy Connect Auth doc. Because of the importance of ensuring user trust and privacy, we are asking you to complete one of the above steps in the next 48 hours. If you fail to do so, your site may be subject to one of the enforcement actions outlined in our policies. If you have any questions or believe you have received this message in error, please contact us. Facebook Developer Relations

多分認証システムが古い(OAuth 2.0を使ってない)かつ、該当のページに<iframe>などのタグがあるのを条件としてFacebook側が検知してたと思います、別にサードパーティにどうこうした訳ではなく。

ソースの確認

まずユーザ認証のところのソースを確認しましょう。
古い認証システムを使う場合これに似てるはずです。
ソースはFacebookのhttp://developers.facebook.com/docs/authentication/connect_auth/より。

 $api_key = "YOUR_API_KEY";
 $interstitial_page = "YOUR_SECURE_URL"; //URL with no 3rd party apps

 $url='http://www.facebook.com/login.php?api_key=' . $app_id
   . '&session_version=3&next=' . urlencode($interstitial_page)
   . '&v=1.0&return_session=1&fbconnect=1'
   . '&cancel_url=' . urlencode($interstitial_page);

 echo "Welcome to the Old Auth flow";
 echo "<p>";

 echo("<a href='" . $url . "'>"
   . "<img src='http://static.ak.facebook.com/images/"
   . "devsite/facebook_login.gif'></a>");

この場合nextパラメータで指定したページに行く時、URLパラメータでuidとかaccess_tokenが渡されますので、危ないと。

OAuth 2.0を使ったログインURLはこうです。

https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&scope=email,read_stream

改修

メールで書かれた通り一つはOAuth2.0に移行する、一つは「中間ページ」挟んでユーザ情報をセッションに保持して隠蔽する。

OAuthについてはhttps://developers.facebook.com/docs/authentication/で詳しく説明しています。

後者の場合はhttp://developers.facebook.com/docs/authentication/connect_auth/の最後でサンプルコードがあるので参考できます。