2011-09-08 15 views
0

http://developers.facebook.com/docs/authentication/で与えられたFacebook認証の例では、auth_requestのstatus部分に情報のランダムなグループを挿入してCSRFを防止しようとしています。そのauth_requestが返ってくると、コードは同じランダムグループがリクエストとともに返されたことを確認します。それがCSRFをどのようにしていますか?Facebook認証の例CSRF

コード:

<?php 

    $app_id = "YOUR_APP_ID"; 
    $app_secret = "YOUR_APP_SECRET"; 
    $my_url = "YOUR_URL"; 

    session_start(); 
    $code = $_REQUEST["code"]; 

    if(empty($code)) { 
    $_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection 
    $dialog_url = "http://www.facebook.com/dialog/oauth?client_id=" 
     . $app_id . "&redirect_uri=" . urlencode($my_url) . "&state=" 
     . $_SESSION['state']; 

    echo("<script> top.location.href='" . $dialog_url . "'</script>"); 
    } 

    if($_REQUEST['state'] == $_SESSION['state']) { 
    $token_url = "https://graph.facebook.com/oauth/access_token?" 
     . "client_id=" . $app_id . "&redirect_uri=" . urlencode($my_url) 
     . "&client_secret=" . $app_secret . "&code=" . $code; 

    $response = file_get_contents($token_url); 
    $params = null; 
    parse_str($response, $params); 

    $graph_url = "https://graph.facebook.com/me?access_token=" 
     . $params['access_token']; 

    $user = json_decode(file_get_contents($graph_url)); 
    echo("Hello " . $user->name); 
    } 
    else { 
    echo("The state does not match. You may be a victim of CSRF."); 
    } 

?> 

情報のビットがここで要求に追加されます。

if(empty($code)) { 
    $_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection 
    $dialog_url = "http://www.facebook.com/dialog/oauth?client_id=" 
     . $app_id . "&redirect_uri=" . urlencode($my_url) . "&state=" 
     . $_SESSION['state']; 

    echo("<script> top.location.href='" . $dialog_url . "'</script>"); 
    } 

そして、ここでチェック:彼らは同じを持って確実にどのよう

if($_REQUEST['state'] == $_SESSION['state']) 

を「状態」はCSRFがないことを保証しますか?

おかげ

答えて

4

ハッシュ(または状態)ウェブサービス(Facebookの)への要求ごとに使用することで生成され、サーバー上のセッションに保存されています。このハッシュは、あなたのウェブサイトからFacebookにリクエストと共に送られます。 Facebookはレスポンスのパラメータとして全く同じハッシュを返します。

リクエストの前に生成されたハッシュが応答のものと一致するかどうかを確認するだけです。

MyWebsite | Facebook 
---------------+----------------- 
       | 
Generate $hash | 
    Store $hash | 
       | 
      $hash 
    -----------------------> 
       | 
      $hash 
    <----------------------- 
       | 
    Check $hash | 

これにより、要求ごとにハッシュが異なるため、CSRFが防止されます。明らかに、各リクエストに同じ文字列を使用すると、それを知っている(または推測している)誰でも応答を偽造することができます。

リクエストが完了したら、セッションのハッシュをチェックして、レスポンスのハッシュが一致するようにします。一致しない場合、偽造された応答になる可能性があります。チェックした後、再度値を入力する必要がないので、セッションから値をクリアします。

Facebookの実装だけでなく、一般的なケースでは、ハッシュのタイムアウトも保存することが賢明です。これにより、不完全な要求からのハッシュが後で使用/悪用されるのを防ぐことができます。すべてのアプリケーションとケースに適合する単一の時間はありませんが、このようなセカンダリ要求/アクションの場合、30秒〜1分です。

+0

この攻撃の仕組みについてのシナリオを教えてください。 – Roman

+0

@Romanインターネットには多くの攻撃や予防の例があります。 [OWASP](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)#Examples)、[Wikipedia](http://en.wikipedia.org/wiki/Cross-site_request_forgery#Example_and_characteristics) 、[Jeffのブログ](http://www.codinghorror.com/blog/2008/10/preventing-csrf-and-xsrf-attacks.html) – adlawson

+0

ありがとうございます、私はすでにそれらを見てきましたが、私たちが取引所から州を省略すると、どのくらい正確に攻撃がFacebookの仕事に役立つのでしょうか。 – Roman