1.服務(wù)端進(jìn)行CSRF防御
服務(wù)端的CSRF方式方法很多樣僧凤,但總的思想都是一致的灯萍,就是在客戶(hù)端頁(yè)面增加偽隨機(jī)數(shù)剂娄。
(1).Cookie Hashing(所有表單都包含同一個(gè)偽隨機(jī)值):
這可能是最簡(jiǎn)單的解決方案了艾栋,因?yàn)楣粽卟荒塬@得第三方的Cookie(理論上)乏苦,所以表單中的數(shù)據(jù)也就構(gòu)造失敗了:>
//構(gòu)造加密的Cookie信息
$value?=?“DefenseSCRF”;
setcookie(”cookie”,?$value,?time()+3600);
?>
在表單里增加Hash值畅形,以認(rèn)證這確實(shí)是用戶(hù)發(fā)送的請(qǐng)求养距。
$hash?=?md5($_COOKIE['cookie']);
?>
”>
然后在服務(wù)器端進(jìn)行Hash值驗(yàn)證
if(isset($_POST['check']))?{
$hash?=?md5($_COOKIE['cookie']);
if($_POST['check']?==?$hash)?{
doJob();
}?else?{
//...
}
}?else?{
//...
}
?>
這個(gè)方法個(gè)人覺(jué)得已經(jīng)可以杜絕99%的CSRF攻擊了,那還有1%呢....由于用戶(hù)的Cookie很容易由于網(wǎng)站的XSS漏洞而被盜取日熬,這就另外的1%棍厌。一般的攻擊者看到有需要算Hash值,基本都會(huì)放棄了,某些除外耘纱,所以如果需要100%的杜絕敬肚,這個(gè)不是最好的方法。
(2).驗(yàn)證碼
這個(gè)方案的思路是:每次的用戶(hù)提交都需要用戶(hù)在表單中填寫(xiě)一個(gè)圖片上的隨機(jī)字符串束析,厄....這個(gè)方案可以完全解決CSRF艳馒,但個(gè)人覺(jué)得在易用性方面似乎不是太好,還有聽(tīng)聞是驗(yàn)證碼圖片的使用涉及了一個(gè)被稱(chēng)為MHTML的Bug员寇,可能在某些版本的微軟IE中受影響弄慰。
(3).One-Time Tokens(不同的表單包含一個(gè)不同的偽隨機(jī)值)
在實(shí)現(xiàn)One-Time Tokens時(shí),需要注意一點(diǎn):就是“并行會(huì)話(huà)的兼容”蝶锋。如果用戶(hù)在一個(gè)站點(diǎn)上同時(shí)打開(kāi)了兩個(gè)不同的表單陆爽,CSRF保護(hù)措施不應(yīng)該影響到他對(duì)任何表單的提交“饴疲考慮一下如果每次表單被裝入時(shí)站點(diǎn)生成一個(gè)偽隨機(jī)值來(lái)覆蓋以前的偽隨機(jī)值將會(huì)發(fā)生什么情況:用戶(hù)只能成功地提交他最后打開(kāi)的表單慌闭,因?yàn)樗衅渌谋韱味己蟹欠ǖ膫坞S機(jī)值。必須小心操作以確保CSRF保護(hù)措施不會(huì)影響選項(xiàng)卡式的瀏覽或者利用多個(gè)瀏覽器窗口瀏覽一個(gè)站點(diǎn)第献。
以下我的實(shí)現(xiàn):
1).先是令牌生成函數(shù)(gen_token()):
function?gen_token()?{
//這里我是貪方便贡必,實(shí)際上單使用Rand()得出的隨機(jī)數(shù)作為令牌,也是不安全的庸毫。
//這個(gè)可以參考我寫(xiě)的Findbugs筆記中的《Random object created and used only once》
$token?=?md5(uniqid(rand(),?true));
return?$token;
}
2).然后是Session令牌生成函數(shù)(gen_stoken()):
function?gen_stoken()?{
$pToken = "";
if($_SESSION[STOKEN_NAME]? ==?$pToken){
//沒(méi)有值仔拟,賦新值
$_SESSION[STOKEN_NAME]?=?gen_token();
}
else{
//繼續(xù)使用舊的值
}
}
?>
3).WEB表單生成隱藏輸入域的函數(shù):
function gen_input() {
gen_stoken();
echo “
value=\”" . $_SESSION[STOKEN_NAME] . “\”> “;
}
?>
4).WEB表單結(jié)構(gòu):
session_start();
include(”functions.php”);
?>
5).服務(wù)端核對(duì)令牌: