CSRF 攻擊可以使用以下方法來防護(hù):
進(jìn)行同源檢測,服務(wù)器根據(jù) http 請(qǐng)求頭中 origin 或者 referer 信息來判斷請(qǐng)求是否為允許訪問的站點(diǎn),從而對(duì)請(qǐng)求進(jìn)行過濾。當(dāng) origin 或者 referer 信息都不存在的時(shí)候,直接阻止請(qǐng)求。這種方式的缺點(diǎn)是有些情況下 referer 可以被偽造,同時(shí)還會(huì)把搜索引擎的鏈接也給屏蔽了。所以一般網(wǎng)站會(huì)允許搜索引擎的頁面請(qǐng)求,但是相應(yīng)的頁面請(qǐng)求這種請(qǐng)求方式也可能被攻擊者給利用。(Referer 字段會(huì)告訴服務(wù)器該網(wǎng)頁是從哪個(gè)頁面鏈接過來的)
使用 CSRF Token 進(jìn)行驗(yàn)證,服務(wù)器向用戶返回一個(gè)隨機(jī)數(shù) Token ,當(dāng)網(wǎng)站再次發(fā)起請(qǐng)求時(shí),在請(qǐng)求參數(shù)中加入服務(wù)器端返回的 token ,然后服務(wù)器對(duì)這個(gè) token 進(jìn)行驗(yàn)證。這種方法解決了使用 cookie 單一驗(yàn)證方式時(shí),可能會(huì)被冒用的問題,但是這種方法存在一個(gè)缺點(diǎn)就是,我們需要給網(wǎng)站中的所有請(qǐng)求都添加上這個(gè) token,操作比較繁瑣。還有一個(gè)問題是一般不會(huì)只有一臺(tái)網(wǎng)站服務(wù)器,如果請(qǐng)求經(jīng)過負(fù)載平衡轉(zhuǎn)移到了其他的服務(wù)器,但是這個(gè)服務(wù)器的 session 中沒有保留這個(gè) token 的話,就沒有辦法驗(yàn)證了。這種情況可以通過改變 token 的構(gòu)建方式來解決。
對(duì) Cookie 進(jìn)行雙重驗(yàn)證,服務(wù)器在用戶訪問網(wǎng)站頁面時(shí),向請(qǐng)求域名注入一個(gè)Cookie,內(nèi)容為隨機(jī)字符串,然后當(dāng)用戶再次向服務(wù)器發(fā)送請(qǐng)求的時(shí)候,從 cookie 中取出這個(gè)字符串,添加到 URL 參數(shù)中,然后服務(wù)器通過對(duì) cookie 中的數(shù)據(jù)和參數(shù)中的數(shù)據(jù)進(jìn)行比較,來進(jìn)行驗(yàn)證。使用這種方式是利用了攻擊者只能利用 cookie,但是不能訪問獲取 cookie 的特點(diǎn)。并且這種方法比 CSRF Token 的方法更加方便,并且不涉及到分布式訪問的問題。這種方法的缺點(diǎn)是如果網(wǎng)站存在 XSS 漏洞的,那么這種方式會(huì)失效。同時(shí)這種方式不能做到子域名的隔離。
在設(shè)置 cookie 屬性的時(shí)候設(shè)置 Samesite ,限制 cookie 不能作為被第三方使用,從而可以避免被攻擊者利用。Samesite 一共有兩種模式,一種是嚴(yán)格模式,在嚴(yán)格模式下 cookie 在任何情況下都不可能作為第三方 Cookie 使用,在寬松模式下,cookie 可以被請(qǐng)求是 GET 請(qǐng)求,且會(huì)發(fā)生頁面跳轉(zhuǎn)的請(qǐng)求所使用。