知了堂Java | Java基礎(chǔ)面試題(13)

6.什么是 CSRF 攻擊,如何避免?
CSRF(Cross-site request forgery)也被稱為 one-click attack或者 session riding,中文全稱是叫跨 站請(qǐng)求偽造。一般來(lái)說(shuō),攻擊者通過(guò)偽造用戶的瀏覽器的請(qǐng)求,向訪問一個(gè)用戶自己曾經(jīng)認(rèn)證訪問過(guò)的 網(wǎng)站發(fā)送出去,使目標(biāo)網(wǎng)站接收并誤以為是用戶的真實(shí)操作而去執(zhí)行命令。常用于盜取賬號(hào)、轉(zhuǎn)賬、發(fā) 送虛假消息等。攻擊者利用網(wǎng)站對(duì)請(qǐng)求的驗(yàn)證漏洞而實(shí)現(xiàn)這樣的攻擊行為,網(wǎng)站能夠確認(rèn)請(qǐng)求來(lái)源于用 戶的瀏覽器,卻不能驗(yàn)證請(qǐng)求是否源于用戶的真實(shí)意愿下的操作行為?
如何避免
1、驗(yàn)證 HTTP Referer 字段?
HTTP頭中的Referer字段記錄了該 HTTP 請(qǐng)求的來(lái)源地址。在通常情況下,訪問一個(gè)安全受限頁(yè)面的請(qǐng) 求來(lái)自于同一個(gè)網(wǎng)站,而如果黑客要對(duì)其實(shí)施 CSRF 攻擊,他一般只能在他自己的網(wǎng)站構(gòu)造請(qǐng)求。因此,可以通過(guò)驗(yàn)證Referer值來(lái)防御CSRF 攻擊?
2、使用驗(yàn)證碼?
關(guān)鍵操作頁(yè)面加上驗(yàn)證碼,后臺(tái)收到請(qǐng)求后通過(guò)判斷驗(yàn)證碼可以防御CSRF。但這種方法對(duì)用戶不太友 好
3、在請(qǐng)求地址中添加token并驗(yàn)證?
CSRF 攻擊之所以能夠成功,是因?yàn)楹诳涂梢酝耆珎卧煊脩舻恼?qǐng)求,該請(qǐng)求中所有的用戶驗(yàn)證信息 都是存在于cookie中,因此黑客可以在不知道這些驗(yàn)證信息的情況下直接利用用戶自己的cookie 來(lái)通過(guò)安全驗(yàn)證。要抵御 CSRF,關(guān)鍵在于在請(qǐng)求中放入黑客所不能偽造的信息,并且該信息不存 在于 cookie 之中??梢栽?HTTP 請(qǐng)求中以參數(shù)的形式加入一個(gè)隨機(jī)產(chǎn)生的 token,并在服務(wù)器端 建立一個(gè)攔截器來(lái)驗(yàn)證這個(gè) token,如果請(qǐng)求中沒有token或者 token 內(nèi)容不正確,則認(rèn)為可能是 CSRF 攻擊而拒絕該請(qǐng)求。這種方法要比檢查 Referer 要安全一些,token 可以在用戶登陸后產(chǎn)生 并放于session之中,然后在每次請(qǐng)求時(shí)把token 從 session 中拿出,與請(qǐng)求中的 token 進(jìn)行比 對(duì),但這種方法的難點(diǎn)在于如何把 token 以參數(shù)的形式加入請(qǐng)求。
對(duì)于 GET 請(qǐng)求,token 將附在請(qǐng)求地址之后,這樣 URL 就變成 http://url? 。?
而對(duì)于 POST 請(qǐng)求來(lái)說(shuō),要在 form 的最后加上 <input type="hidden" name="csrftoken" value="tokenvalue"/> ,這樣就把token以參數(shù)的形式加入請(qǐng)求了
4、在HTTP 頭中自定義屬性并驗(yàn)證?
這種方法也是使用 token 并進(jìn)行驗(yàn)證,和上一種方法不同的是,這里并不是把 token 以參數(shù)的形式置 于 HTTP 請(qǐng)求之中,而是把它放到 HTTP 頭中自定義的屬性里。通過(guò) XMLHttpRequest 這個(gè)類,可以 一次性給所有該類請(qǐng)求加上 csrftoken 這個(gè) HTTP 頭屬性,并把 token 值放入其中。這樣解決了上種方 法在請(qǐng)求中加入 token 的不便,同時(shí),通過(guò) XMLHttpRequest 請(qǐng)求的地址不會(huì)被記錄到瀏覽器的地址 欄,也不用擔(dān)心 token 會(huì)透過(guò) Referer 泄露到其他網(wǎng)站中去