參考:
https://blog.csdn.net/houdabiao/article/details/83058351
https://zhuanlan.zhihu.com/p/22521378?utm_source=wechat_session&utm_medium=social&utm_oi=1003056052560101376&from=singlemessage&isappinstalled=0
https://blog.csdn.net/xiaoxinshuaiga/article/details/80766369
https://www.jianshu.com/p/67408d73c66d
1 幾種形式:
1.1 get
<img src="http://bank.example/withdraw?amount=10000&for=hacker" >
可以本域一些外鏈圖片等功能做,也能在外域做
1.2 post
<form action="http://bank.example/withdraw" method=POST> <input type="hidden" name="account" value="xiaoming" /> <input type="hidden" name="amount" value="10000" /> <input type="hidden" name="for" value="hacker" /> </form> <script> document.forms[0].submit(); </script>
必須在外域做
1.3 鏈接
<a href="http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank"> 重磅消息!! <a/>
可以本域一些外鏈圖片等功能做,也能在外域做
2 攻擊源
2.1 跨域
2.2 本域
3 防護
3.1 盡量使用POST,限制GET
當然POST並不是萬無一失,攻擊者只要構造一個form就可以,但需要在 第三方頁面做,這樣就增加暴露的可能性。 增加攻擊成本
origin | referer | 備注 | |
uri路徑 | 無 | 有 | |
get | 無 | 有 | 隨便瀏覽器點一個超鏈接(get),發現referer暴露了,而且還暴露了uri |
當Origin和Referer頭文件不存在時該怎么辦?如果Origin和Referer都不存在,建議直接進行阻止
3.2.1 前面說過,CSRF大多數情況下來自第三方域名,但並不能排除本域發起。如果攻擊者有權限在本域發布評論(含鏈接、圖片等,統稱UGC),那么它可以直接在本域發起攻擊,這種情況下同源策略無法達到防護的作用。
3.2.2 而且瀏覽器的這兩個字段,有可能被篡改,服務器 不能完全信任瀏覽器
3.2.3 用戶可以選擇關閉referer origin
3.3 請求頭或體中加入_csrf_token,與cookie或session的_csrf_token作對比,可直接相等,也可加解密對比
token 在每次請求時把 token 從 session 或 cookie 中拿出,與請求頭或體中的 token 進行比對
通常使用的方法就是在每次頁面加載時,使用 javascript 遍歷整個 dom 樹,對於 dom 中所有的 a 和 form 標簽后加入 token
24netty(二十)http代理服務器 中的目標服務器即是使用header_token+cookie方式防御csrf
HOST其實無所謂,是服務端的域名,一個IP地址可以對應多個域名: 一台虛擬主機(服務器)只有一個ip,上面可以放成千上萬個網站。當對這些網站的請求到來時,服務器根據Host這一行中的值來確定本次請求的是哪個具體的網站
origin: https://a.com:port
referer: https://a.com:port/xx/xx(只有post請求會帶上)
host: b.com:port
附1
Origin字段的方式比Referer更人性化,因為它尊重了用戶的隱私。
(1)Origin字段里只包含是誰發起的請求,並沒有其他信息 (通常情況下是方案,主機和活動文檔URL的端口)。跟Referer不一樣的是,Origin字段並沒有包含涉及到用戶隱私的URL路徑和請求內容,這個尤其重要。
(2)Origin字段只存在於POST請求,而Referer則存在於所有類型的請求。
隨便點擊一個超鏈接(比如從搜索列表里或者企業intranet),並不會發送Origin字段,這樣可以防止敏感信息的以外泄露。
在應對隱私問題方面,Origin字段的方法可能更能迎合用戶的口味。