深入理解CSRF攻击与防御

What is CSRF

首先可以先看一段英文原文介绍:
Cross Site Reference Forgery works by including malicious code or a link in a page that accesses a web application that the user is believed to have authenticated. If the session for that web application has not timed out, an attacker may execute unauthorized commands.
CSRF全称为跨站请求伪造(Cross-site request forgery),是一种网络攻击方式,也被称为 one-click attack 或者 session riding, 缩写为:CSRF/XSRF。

CSRF攻击原理

CSRF攻击可以利用网站对于用户网页浏览器的信任,挟持用户当前已登陆的Web应用程序,去执行并非用户本意的操作。
简单来说,就是攻击者盗用了你的身份,以你的名义发送恶意请求。

CSRF攻击的大致步骤:

1.登录受信任网站A,并在本地生成Cookie。
2.在不登出A的情况下,访问危险网站B。
3.B站利用已经验证的a.com的cookie,伪造用户请求访问A。
CSRF原理解析图
CS=Cross Site,跨站,从b.com发起
RF=Request Forgery,利用已经验证的a.com的cookie,从b.com向a.com中的某个页面performclick.aspx发起页面的请求,由于在同一个浏览器中共享cookie,因此这个请求看起来像a.com自己发出的,因此是请求伪造。

CSRF有一些特点:
1 b.com是从前端攻击,即从用户的浏览器发起的,因为其他地方(例如b.com的后端)就无法通过共享cookie来伪造请求
2 可以伪造的请求,与a.com存在CSRF漏洞的页面有关。b.com可以通过GET方式和POST方式,伪造请求给a.com站点;但无法通过Ajax进行请求伪造,这是因为浏览器遵循的Ajax的跨域限制。
3 CSRF危害更多是针对可以进行业务动作(增删改)的页面,通过伪造请求欺骗站点进行业务办理。对于查询页面存在CSRF漏洞,由于浏览器跨域限制,即使请求返回数据,B.com的页面是无法对数据进行分析或处理,因此查询页面的CSRF危害会小很多,或者没有危害。

How to defense CSRF

在讨论如何抵御 CSRF 之前,先要明确 CSRF 攻击的对象,也就是要保护的对象。
通过理解CSRF攻击原理可知,CSRF 攻击是黑客借助受害者的 cookie 骗取服务器的信任,然后去伪造用户请求。但是黑客并不能拿到 cookie,也看不到 cookie 的内容。另外,对于服务器返回的结果,由于浏览器同源策略的限制,黑客也无法进行解析。因此,黑客无法从返回的结果中得到任何东西,他所能做的就是给服务器发送请求,以执行请求中所描述的命令,在服务器端直接改变数据的值,而非窃取服务器中的数据。
所以,我们要保护的对象是那些可以直接产生数据改变的服务,而非读取查询数据的服务。
在业界目前防御 CSRF 攻击主要有四种策略:验证 HTTP Referer 字段;在请求地址中添加 token 并验证;在 HTTP 头中自定义属性并验证;加验证码。下面就分别对这三种策略进行详细介绍。

验证 HTTP Referer 字段

根据 HTTP 协议,在 HTTP 头中有一个字段叫 Referer,它记录了该 HTTP 请求的来源地址。要防御 CSRF 攻击,只需要针对每一个可以改变数据的服务请求,验证其 Referer 值,如果是以正确的域名开头,则说明该请求是合法的。如果 Referer 是其他网站的话,则有可能是黑客的 CSRF 攻击,拒绝该请求。
但这种方法并非万无一失,对于某些浏览器,比如 IE6 或 FF2,目前已经有一些方法可以篡改 Referer 值。如果黑客能够篡改 Referer 值,这样就可以通过验证,从而进行 CSRF 攻击。

在请求地址中添加 token 并验证

要抵御 CSRF,关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于 cookie 之中。简而言之就是在客户端页面增加伪随机数。
在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。
这种防御方法要比检查 Referer 要安全一些,token 可以在用户登陆后产生并放于 session 之中,然后在每次请求时把 token 从 session 中拿出,与请求中的 token 进行比对。

在 HTTP 头中自定义属性并验证

这种方法也是使用 token 并进行验证,和上一种方法不同的是,这里并不是把 token 以参数的形式置于 HTTP 请求之中,而是把它放到 HTTP 头中自定义的属性里。服务端的CSRF防御方法很多样,但总的思想都是一致的,就是在客户端页面增加伪随机数。

验证码

每次的用户提交都需要用户在表单中填写一个图片上的随机字符串,但可能会降低用户体验。

部分参考资料

http://shiflett.org/articles/cross-site-request-forgeries
https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
https://www.jianshu.com/p/00fa457f6d3e
https://blog.csdn.net/xiongzhengxiang/article/details/29869515

总结

本文主要是结合自己所学知识,探讨了一些对CSRF的一些理解,CSRF 是一种危害非常大的攻击,又很难以防范。目前几种防御策略虽然可以很大程度上抵御 CSRF 的攻击,但并没有一种完美的解决方案。在这之前,只有充分重视 CSRF,根据系统的实际情况选择最合适的策略,这样才能把 CSRF 的危害降到最低。
希望能对大家有所帮助~ 有问题欢迎留言交流,不足之处还请多多指正。

展开阅读全文

没有更多推荐了,返回首页