2011-09-08 2 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은 응답의 매개 변수와 똑같은 해시를 반환합니다.

요청 전에 생성 된 해시가 응답의 요청과 일치하는지 확인하십시오.

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) , [제프의 블로그] (http://www.codinghorror.com/blog/2008/10/preventing-csrf-and-xsrf-attacks.html) – adlawson

+0

고마워, 나는 이미 그걸 봤어. 그래도 알아 내는데 어려움이있다. 우리가 교환에서 국가를 생략하면 공격이 페이스 북과 얼마나 정확하게 작용할 것인가. – Roman