参考:
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字段的方法可能更能迎合用户的口味。