说说 XSRF 防范
這是我在知乎的一個回答。原提問是如何在單頁應(yīng)用下進(jìn)行 XSRF 防護(hù)。
XSRF(CSRF) 攻擊的原理是什么?就是攻擊者能猜測出所有的需要提交的內(nèi)容以及類型,所以所有的解決方案共同出發(fā)點(diǎn)就是加一個攻擊者也不知道隨機(jī)值發(fā)送給后端驗(yàn)證就可以防范。
有很多解決方案,cookie-session,很不友好的所有表單都得填寫驗(yàn)證碼,還有一種很少人知道 JSON Web Token。
驗(yàn)證碼(圖形或者手機(jī))這種就不說了吧,這個在互聯(lián)網(wǎng)場景中因?yàn)橛脩趔w驗(yàn)原因幾乎沒有應(yīng)用的。
首先要知道直接讓后端驗(yàn)證 cookie 是否存在正確是不可取的,因?yàn)樗姓埱蠖紩詣痈綆д埱笏谟虻?cookie,當(dāng)然只驗(yàn)證 http referrer 也是不靠譜的。
正確的方式是當(dāng)用戶進(jìn)行登錄請求的時候,這時候后端應(yīng)該把包含 xsrf 字段的 cookie 保存在 session 中并且返還給前端,前端需要獲取到 cookie 中的值并且能放入 ajax 請求體或請求頭中,后端把這個值與 session 中的相應(yīng)值進(jìn)行判斷就可以了,根據(jù)跨域不可訪問不同域的 cookie ,攻擊者也很難猜測出 xsrf 的值,那么這樣就防范了 xsrf 攻擊。
所以這里對 xsrf cookie 不能設(shè)置 httpOnly(當(dāng)然就會有 XSS 問題,后面會提),同時提一句所以的 Token 必須得讓后端設(shè)置 expire 過期時間。
這個 axios 就提供了這個功能,只要設(shè)置約定好 xsrf cookie字段名就可以了,axios 獲取到值后默認(rèn)是放入 request header 中,這也是業(yè)界最流行的方式。
如果不是單頁應(yīng)用都是后端在表單中加入一個隱藏的表單域。
<input type="hidden" name="_token" value="lAfHB..">當(dāng)然還有JWT,這個主要應(yīng)用場景是 app,因?yàn)?app 通常沒有 Cookie,當(dāng)然也有應(yīng)用到 Web 中的,要講這個就有點(diǎn)多了,和上述也差不多。
簡單說,JWT 就是服務(wù)端和客戶端約定好一個Token格式,最后用密鑰進(jìn)行簽名 base64 編碼后放入請求頭即可,客戶端存放這個簽名的內(nèi)容通常會放在 localstorage 中,也有放在 cookie 中的。JWT應(yīng)用了哈希簽名的密碼學(xué)技術(shù),相比 cookie-session 的方式就是服務(wù)端可以不用(在內(nèi)存或者緩存)存放 session,能節(jié)省存儲資源,不過同時服務(wù)器需要通過計(jì)算來驗(yàn)證也浪費(fèi)了計(jì)算資源。詳細(xì)的說明可以參考:講真,別再使用JWT了!
現(xiàn)有的產(chǎn)品為了更安全還需要考慮 XSS 攻擊,這個就是有些惡意腳本或者插件不存在跨域問題,所以能獲取到 cookie 和 localstorage 的值。
很安全的方式就是把 XSRF Token 加入到 JWT 中,并且把 JWT 存放在設(shè)置 httpOnly 的 cookie 中,然后單獨(dú)把 XSRF Token 設(shè)置在 httpOnly=false 的 cookie 中,前端請求時,需要獲取 XSRF Token 并放入請求頭(RequestHeader)。服務(wù)器端可以直接驗(yàn)證JWT中XSRF的值和XSRF的值即可。因?yàn)橛昧斯C荑€簽名的技術(shù),這樣就可以防止篡改內(nèi)容。
這樣的安全防護(hù)就能抵御所有的 XSRF 攻擊了。
總結(jié)
以上是生活随笔為你收集整理的说说 XSRF 防范的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hyper-V 2016 系列教程26
- 下一篇: mysql批量插入:语法