Token驗(yàn)證機(jī)制是防范csrf攻擊的核心手段。其基本思路是服務(wù)器在用戶訪問(wèn)頁(yè)面時(shí)生成唯一、不可預(yù)測(cè)的token,嵌入到頁(yè)面表單中,并保存在用戶Session中;當(dāng)用戶提交請(qǐng)求時(shí),服務(wù)器校驗(yàn)表單中的token與session中的是否一致,防止攻擊者偽造請(qǐng)求。實(shí)現(xiàn)步驟包括:1.生成token,使用加密安全的隨機(jī)數(shù)方法;2.將token存入頁(yè)面和會(huì)話,作為隱藏字段插入html表單并保存至session;3.提交時(shí)校驗(yàn)token,確保兩者匹配;4.可選每次請(qǐng)求更新token以增強(qiáng)安全性。注意事項(xiàng)包括:不要將token放在Cookie中傳輸,token生命周期不宜過(guò)長(zhǎng),區(qū)分get和post請(qǐng)求,ajax請(qǐng)求也需加token驗(yàn)證。其他補(bǔ)充防護(hù)手段有samesite cookie屬性、雙重提交cookie模式和referer頭校驗(yàn)。
CSRF(跨站請(qǐng)求偽造)是一種常見的web安全攻擊方式,攻擊者通過(guò)誘導(dǎo)用戶點(diǎn)擊惡意鏈接,利用用戶在已登錄網(wǎng)站的身份發(fā)起非自愿的請(qǐng)求。防范CSRF的核心手段之一就是使用Token驗(yàn)證機(jī)制。
什么是Token驗(yàn)證機(jī)制?
Token驗(yàn)證機(jī)制的基本思路是:服務(wù)器在用戶訪問(wèn)需要保護(hù)的頁(yè)面時(shí)生成一個(gè)唯一的、不可預(yù)測(cè)的Token,并將其嵌入到頁(yè)面中(通常是表單中),當(dāng)用戶提交請(qǐng)求時(shí),服務(wù)器會(huì)驗(yàn)證該Token是否合法。如果Token不匹配或缺失,就拒絕執(zhí)行請(qǐng)求。
這種方式有效防止了跨站請(qǐng)求,因?yàn)楣粽邿o(wú)法輕易獲取用戶的Token值。
如何實(shí)現(xiàn)Token驗(yàn)證機(jī)制?
要實(shí)現(xiàn)Token驗(yàn)證機(jī)制,主要分為以下幾個(gè)步驟:
-
生成Token
每次用戶訪問(wèn)敏感操作頁(yè)面(如修改密碼、提交訂單等)時(shí),服務(wù)器應(yīng)生成一個(gè)隨機(jī)且唯一的Token。推薦使用加密安全的隨機(jī)數(shù)生成方法,比如php中的random_bytes()、python的secrets模塊。 -
將Token存入頁(yè)面和會(huì)話
將生成的Token作為隱藏字段插入到HTML表單中,同時(shí)保存在用戶的Session中,以便后續(xù)驗(yàn)證。 -
提交時(shí)校驗(yàn)Token
當(dāng)用戶提交請(qǐng)求時(shí),服務(wù)器從POST數(shù)據(jù)中讀取Token,并與Session中保存的Token進(jìn)行比對(duì)。只有兩者一致時(shí)才處理請(qǐng)求,否則返回錯(cuò)誤。 -
每次請(qǐng)求更新Token(可選)
為了進(jìn)一步增強(qiáng)安全性,可以在每次請(qǐng)求后更換Token,這樣即使Token被截獲,也只能使用一次。
舉個(gè)例子:你在寫一個(gè)用戶修改資料的頁(yè)面,在表單里加入了一個(gè)隱藏字段:
<input type="hidden" name="csrf_token" value="a1b2c3d4e5">
同時(shí)服務(wù)器把這個(gè)值保存在Session里。當(dāng)用戶提交表單時(shí),檢查傳來(lái)的token是否和Session里的匹配。
常見誤區(qū)和注意事項(xiàng)
-
不要把Token放在Cookie里傳輸
如果Token也通過(guò)Cookie發(fā)送,那么在存在xss漏洞的情況下,攻擊者仍可能竊取Token。建議只通過(guò)表單提交或AJAX請(qǐng)求體傳遞Token。 -
Token生命周期不宜過(guò)長(zhǎng)
Token應(yīng)該隨著頁(yè)面刷新而更新,而不是長(zhǎng)期不變。長(zhǎng)時(shí)間使用的Token容易被猜測(cè)或重放攻擊。 -
區(qū)分GET和POST請(qǐng)求
GET請(qǐng)求通常用于獲取數(shù)據(jù),不應(yīng)該引起狀態(tài)變化。對(duì)于所有會(huì)修改狀態(tài)的請(qǐng)求(如刪除、提交、更新),都應(yīng)該啟用CSRF保護(hù)。 -
AJAX請(qǐng)求也要加Token驗(yàn)證
不少人忽略了對(duì)AJAX請(qǐng)求的防護(hù)。可以在頁(yè)面加載時(shí)將Token注入到JavaScript變量中,或者通過(guò)自定義http頭來(lái)傳遞Token。
其他補(bǔ)充防護(hù)手段
雖然Token機(jī)制是防御CSRF的主要手段,但還可以結(jié)合以下方式加強(qiáng)防護(hù):
-
SameSite Cookie屬性
設(shè)置Cookie的SameSite=Strict或Lax可以阻止瀏覽器在跨站請(qǐng)求中自動(dòng)攜帶Cookie,從而降低CSRF風(fēng)險(xiǎn)。 -
雙重提交Cookie模式(double Submit Cookie)
這種方式要求前端在請(qǐng)求頭或參數(shù)中帶上Token,同時(shí)服務(wù)器也將其設(shè)置為Cookie。服務(wù)器對(duì)比這兩個(gè)值是否一致。適合無(wú)Session的場(chǎng)景,但不如服務(wù)端存儲(chǔ)更安全。 -
Referer頭校驗(yàn)(謹(jǐn)慎使用)
雖然可以通過(guò)檢查請(qǐng)求來(lái)源的Referer判斷是否為跨站請(qǐng)求,但有些瀏覽器或代理會(huì)屏蔽Referer信息,可能導(dǎo)致誤判。
基本上就這些,CSRF防護(hù)并不復(fù)雜,但很容易在細(xì)節(jié)上出錯(cuò)。只要在關(guān)鍵操作中加上Token驗(yàn)證,再配合一些額外策略,就能大大提升應(yīng)用的安全性。