2014-09-22 19 views
0

我試圖通過在每一個上生成一個唯一的標記來確保我的表單不受CSRF攻擊。我有一個生成一個獨特的標記,像這樣我的窗體上的隱藏字段:如何將一個PHP表單上生成的令牌傳遞給處理它的表單?

public static function generateToken() { 
     return $_SESSION['token'] = md5(uniqid(mt_rand(), TRUE)); 
} 

我知道,MD5被貶值,不應該被使用,因爲它不是像隨機:

base64_encode(openssl_random_psuedo_bytes(32)); 

但我目前沒有安裝ssl,我會照顧這個。但我的主要問題是,產生此標記後存入會話,用戶目前在像這樣:

$_SESSION['token'] = $_POST['token']; 

它吸引的是在它生成的令牌中的字段的值。現在我將這個令牌存儲到會話中,我需要弄清楚將它發送到處理文件。我在這個表格中有很多字段,因此在一個if()聲明中檢查每個單詞都會顯得有點奇怪。我想我想說的是,如何在處理數據的表單上檢查此令牌,並且如果令牌與表單上生成的令牌不相同,我是否可以拒絕該數據?只需使用die()殺死處理腳本?

我也想知道如果我甚至需要這樣做 - 我已經閱讀了CSRF,但我想最糟糕的人可以做的是改變一些正在發送的信息處理,這就是爲什麼我'想要通過令牌來檢查和拒絕數據是發生這種情況。

<form name="form1" action="processing.php" method="POST" enctype="multipart/form-data"> 

這就是我所說的其他文件。 PHP不是都在一個地方,我通過$ _POST方法獲取處理腳本中的所有內容。

+0

我們需要生成它的令牌存儲在會話,也具有相同價值形態有場呼應的是說。當表單被提交時,我們需要檢查/比較我們在會話中保存的值,以驗證我們呈現的表單是否僅提交,但不是來自不同網站的某些隨機表單提交給我們的網站。 – Sunand 2014-09-22 19:40:23

回答

0
  1. 生成和保存令牌服務器端(SQL或其他..)
  2. 創建令牌(客戶端)的cookie
  3. 當窗體的就是提交,檢索cookie中的令牌
  4. 如果餅乾比保存令牌相同的,這就是確定

生成令牌:

$formName = "signin"; // name of the form 
$ip  = get_ip(); // create a function to get the ip of the user 
$salt  = "8077_(-(àyhvboyr(à"; // uniq secret salt 
$token = md5(sha1($salt.$ip).sha1($salt.$formName)); 
... 

if(empty($_COOKIE['token'])){ // if(empty($_SESSION['token'])){ 

    setcookie("token",$token, time()+3600*1); // use with cookie // time()+3600*1 = now + 1 hour 
    $_SESSION['token'] = $token; // OR use with session 

}else{ 

    // when the form is submit regenerate the token and compare with the request token 
    if($_COOKIE['token'] == $token){ // OR if($_SESSION['token'] == $token){ 
     // request from server - ok 
     // ... 
    }else{ 
     // bad request 
     setcookie("token",0); // destruct cookie 
     $_SESSION['token'] = ""; // OR destruct session 
     // redirect at the first form 
    } 
} 


<form> 
    // if you want use the token directly in your form, add this : 
    <input type="hidden" name="token" value="<?php echo $token ?>" /> 
</form> 
+0

我相信我們不應該使用cookie來驗證令牌。它應該是一個表單字段。 – Sunand 2014-09-22 19:24:45

+0

我仍然不確定如何比較表單中字段中生成的令牌,並將其傳遞給服務器上字段令牌和令牌進行比較的處理腳本。如果我們將令牌傳遞給服務器端,它是否仍然是我們最初生成的那個相同的?它如何/爲什麼會改變? – ckmartin 2014-09-22 19:30:21

+0

令牌是由用戶(ip ..)和uniq按表格uniq(例如,您也可以添加時間限制)..所以,您確定用戶沒有更改並且來自您的站點。 – pirs 2014-09-22 19:42:18

0
$formName = "signin"; // name of the form 
$ip  = get_ip(); // create a function to get the ip of the user 
$salt  = "8077_(-(àyhvboyr(à"; // uniq secret salt 
$token = md5(sha1($salt.$ip).sha1($salt.$formName)); 

$_SESSION["token"]=$token; 
... 
<form action="submit.php" > 
// if you want use the token directly in your form, add this : 
<input type="hidden" name="token" value="<?php echo $token ?>" /> 
</form> 

和submit.php我們需要寫類似

if($_SESSION['token'] == $_POST['token']){ 
    // request from server 
}else{ 
    // external request 
} 
+0

@Pirs抱歉,但我只是想說有一個變化。我們需要使用會話而不是cooke – Sunand 2014-09-22 19:47:37

+0

爲什麼'if($ _ POST ['token'] == $ token'被註釋掉了?另外,如果它是來自服務器的請求 - 這意味着可以安全地繼續處理一個外部的請求會是殺死腳本的理由?這對我有很大的幫助Sunand,謝謝! – ckmartin 2014-09-22 19:47:54

+0

@LoudGraveyard做了更改,請檢查 – Sunand 2014-09-22 19:49:53

相關問題