聲明:
由于筆者能力有限,難免出現各種錯誤和漏洞。全文僅作為個人筆記,僅供參考。
筆記内容來源于各類網課
環境:本地伺服器,BurpSuite
一、概述
- 使用token進行CSRF 漏洞防禦。
- BurpSuite生成CSRF POC。
二、漏洞防禦
2.1 漏洞修補邏輯
CSRF漏洞實質:伺服器無法準确判斷目前請求是否是合法使用者的自定義操作。
如果伺服器在使用者登入之後給予使用者一個唯一合法令牌,每一-次操作過程中,伺服器都會驗證令牌是否正确,如果正确那麼執行操作。不正确不執行操作。
一般情況下,給予的令牌會寫入表單中隐藏域的value值中,随着表單内容進行送出。
下圖是沒有token,僅僅利用cookie驗證使用者的模型。
這個模型中,隻要管理者點選惡意頁面或觸發惡意連結,服務的隻是驗證了操作的身份,沒有驗證是不是操作者自定義的操作。

如果利用在增删改中設定唯一令牌(token),執行操作時隻有送出令牌才能操作的話,就可以有效防止CSRF。如果令牌不正确,那麼不執行操作。并給出提示内容。
在下面的模型中,登陸成功後,同時設定的唯一的token。
在使用者操作時,不僅通過cookie驗證使用者身份,還通過token驗證使用者操作的自定義性。
2.2 簡單代碼模型分析
Token作為識别操作是否是目前使用者自己操作的唯一憑證,需要設定為複雜難以被破解的内容。
例如:
生成的tooken是不斷變化的。
<?php
function generate_Token(){
date_default_timezone_set("PRC");
$salt = "JUHnk&*^GG223DF++-@".date("Y/m/d h:i:sa");
$token = md5($salt);
return $token;
}
echo generate_Token()
?>
調用函數檢視生成的token。
2.3 使用Token進行防禦
- 登入驗證成功之後,在會話SESSION["user_ token"]中儲存Token。
- 在背景操作中,增删改表單中添加隐藏域hidden,設定value為Token。
- 送出之後進行驗證Token是否正确。
我們編寫代碼login.php
<?php
session_start();
function generate_Token(){
date_default_timezone_set("PRC");
$salt = "JUHnk&*^GG223DF++-@".date("Y/m/d h:i:sa");
$token = md5($salt);
return $token;
}
$token = generate_Token();
$_SESSION['user_token'] = $token;
?>
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<title>CSRF_Token</title>
</head>
<body>
<h1>CSRF_token</h1>
<form action="check.php" method="POST">
<input type="text" name="user_info" value="hi,token">
<input name="user_token" value="<?php echo $token;?>" hidden>
<button type="submit" class="btn btn-primary">送出</button>
</form>
</body>
</html>
check.php
<?php
session_start();
$user_token = $_POST['user_token'];
if($user_token == $_SESSION['user_token']){
echo 'success'.'<br/>';
}else{
echo 'failed'.'<br/>';
}
echo '<h1>session token:</h1>'.$_SESSION['user_token'].'<br/>';
echo '<h1>you post token:</h1>'.$user_token;
?>
我們測試管理者正常送出。
我們使用BurpSuite生成POC,攔截到請求。
生成的POC,儲存到桌面的poc.html。
我們使用剛才使用浏覽器點選這個惡意網頁。
可以看到登陸失敗,這是由于token不一樣導緻驗證失敗。反應到實際流程中,就是token不一緻,判斷為CSRF攻擊,拒絕執行這項操作。
這樣我們使用token完成了一次CSRF的簡單防禦。上述代碼有很多不完善的地方,這裡僅僅是作為例子展示。