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