csrf与防护,get与post ,origin与referer host区别

参考:

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

GET接口太容易被拿来做CSRF攻击,看上面示例就知道,只要构造一个img标签,而img标签又是不能过滤的数据。接口最好限制为POST使用,GET则无效,降低攻击风险。
当然POST并不是万无一失,攻击者只要构造一个form就可以,但需要在第三方页面做,这样就增加暴露的可能性。增加攻击成本
 
3.2 Origin Header 与 Referer Header,这两个Header在浏览器发起请求时,大多数情况会自动带上,并且不能由前端自定义内容。  服务器可以通过解析这两个Header中的域名,确定请求的来源域。对于Ajax请求,图片和script等资源请求,为发起请求的页面地址。对于页面跳转,为打开页面历史记录的前一个页面地址。因此我们使用Referer中链接的Origin部分可以得知请求的来源域名。
  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字段的方法可能更能迎合用户的口味。

 

posted on 2019-12-29 14:34  silyvin  阅读(1310)  评论(0编辑  收藏  举报