2011-07-11 53 views
4

以下是來自Facebook的身份驗證頁面的示例。將數據添加到會話並使用JavaScript重定向到URL後面的想法是什麼?另外爲什麼做一個uniqid的md5哈希?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."); 
    } 

?> 

回答

3

我知道這可能會得到提名,因爲它是一個維基百科的鏈接,但你可以在這裏找到CSRF的完整說明http://en.wikipedia.org/wiki/Cross-site_request_forgery,一旦你完全明白它是什麼,你就會明白有每個用戶的唯一令牌如何可以防止它。預防部分列出了使用每用戶令牌作爲預防方法。

+0

好的,那麼csrf的功能是捎帶用戶訪問網站。正確?我可以理解關於經過身份驗證的用戶訪問一個頁面並在不知不覺中觸發一個URL的情況。但是,如果上面的代碼插入到每個頭中?這似乎有點沉重。 –

+1

基本上,如果您有一個網站根據帖子或獲取請求發起操作,則您應該始終驗證請求即將發生的地點/方式。 –

1

它確保您在這裏僅被重定向到響應網站發起的操作。在https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29上閱讀CSRF。

+0

我明白了。所以這將是一種在B點(到達)驗證來自A點(起點)的呼叫的方法。你認爲這可以通過PHP內部解決嗎?如果我要檢查來自哪裏的調用,應該可以在服務器變量中看到這一點,如果僞造提供了可以從一個頁面傳遞到另一個頁面的唯一ID。 –

+1

關鍵是它必須是一個不能平分重複的值(因此是md5/uniqid調用)。如果它是一個固定值,那麼專門的攻擊者將能夠推斷出它並製作出一個跨站點請求,SESSION調用確保它是一個無法預期的值。 – Femi

1

通過生成一個難以猜測的值並將其存儲在會話中並將其與請求一起發送,此腳本可以驗證它是否被自己調用,而不是其他地方。在別的地方,難以猜測的價值將是不明確的,因此可能無法提供。

+0

所以從你說的這是驗證請求是否來自預期頁面的一種方法。這會用於每個頁面還是僅用於特定情況? –

+1

這取決於您的應用程序。這是安全和開銷之間的折衷。你可能不在乎是否有人從外面提交給你的聯繫表,直到被認爲他很有趣的人使用,然後用它將你的地獄從你身上炸開。 你可以做的是修正這種想法在表單的抽象中,所以你只需要修復一次。一般來說,我不認爲你希望人們在你的域名之外的某個地方提交表單。 – hoppa