CSRF 跨站域请求伪造白话详解

作者:vkvi 来源:ITPOW(原创) 日期:2015-1-23

CSRF 是什么?

Cross Site Request Forgery, 跨站域请求伪造。

CSRF 怎么攻击?

举个例子,有一个网站内容管理系统,删除信息时用的是 GET 请求,比如 http://www.itpow.com/admin/delete.asp?infoId=1(后面我们将省略 URL 中 admin 及前面的部分)。其中 infoId 就是指示要删除哪条信息。

现在有一个黑客,他写了一个地址 delete.asp?infoId=2,并且把这个网址发给管理员,假如恰好管理员已经登录了后台,此时管理员点击这个链接,infoId 为 2 的那条信息就被误删了。

有人就说,管理员傻呀,这个链接,看不出来?其实有很多方式可以隐藏这个链接,比如黑客用短网址进行跳转,再比如黑客把这个链接作为 <img src="delete.asp?infoId=2" 放在黑客的一个网站中,并诱使管理员去访问。

有人又会说,好吧,但是实现攻击的前提是管理员已经登录,黑客怎么能保证他在攻击的时候管理员恰好已经登录?我们想想,假如我们不是内容管理系统,是邮件系统,黑客向每个邮箱用户发送一个邮件,邮件中就是类似这样的攻击链接——删除 mailId 为 2 的邮件,再写些话语诱导邮箱用户去点击,结果可想而知,因为用户看到这封邮件的时候是已经登录了的。再者,即使不是邮件系统,但是像钱一类的东西,黑客会花费大量的精力来诱使你先登录,然后实施攻击。

防范措施——不用 GET,用 POST?

不用 GET 方式,参数就不能用 QueryString 传,看起来解决了问题,实际没有解决,因为黑客可以写一串 JavaScript 代码,并利用 Ajax 提交,或者做一个隐藏的 form 表单悄悄提交(这些页面可位于黑客的网站上,诱导用户点击),同样能够实现攻击。

所以不用 GET,用 POST 的方式只能防范非常非常初级的黑客(或者他们根本称不上黑客)。

防范措施——使用 Referer 判断来源?

服务器端使用 Referer 判断请求来源,如果不是从本站发起的请求,就拒绝,避免管理员误点黑客发来的链接。

但是同样不能避免,比如我们之前说的邮件系统,链接就在邮件页面,Referer 肯定是正确的,再者 Referer 是浏览器决定的,假如浏览器被攻陷,Referer 也就危险了,对于重要系统,光靠此法显然不稳当。

当然,某些简单的情况下还是适用的。

防范措施——使用 token 令牌?较靠谱

用户登录后,服务器生成一个随机数,存在 session 中,并且给每一个被认可的链接都加上这个 token,比如 delete.asp?infoId=1&token=486586,由于黑客不知道这个 token,所以无法完成攻击。

在添加 token 时一定要注意只给认可的链接加,不要见链接就加,比如前面邮件系统那个例子,别把黑客的链接也给加上 token。

再者别给查询页面加 token,比如邮件系统查看邮件的页面,假如我们加了 token,地址为 view.asp?mailId=1&token=486586,黑客就可以发一个邮件,里面有一个指向黑客的网站链接,用户查看邮件时点击了这个链接,黑客就可以通过 Referer 得知用户是从 view.asp?mailId=1&token=486586 这个页面过来的,那么就有 token 了,那么黑客的程序就跳转到 delete.asp?mailId=2&token=486586,实现了攻击。

这个方法可以防范一些攻击,但是缺点也很明显,每一个链接都要仔细研究,一不小心把不该加的链接加上了,一不小心把该加的搞漏了。再者这种情况一定不能有 XSS 漏洞,否则黑客利用自己构造的 JavaScript 脚本,也可以获取 token 值。当然,上面说的是 GET 提交方式,如果是 POST 提交,则不存在这么多细节。

遍地 CSRF 漏洞?

有些所谓的安全机构,拿起工具一扫,扫到一个公众投票系统,就出报告说这个网站非常不安全。

我认为这是不理智的做法,有没有必要大事小事都混在一起谈?像网上的投票系统,无非就是提高互动性,搞着玩的,有必要上纲上线么?你真要防,防得着么?你看那些微博帐号,全是程序注册的,人家是用软件模拟一个人来使用浏览器,服务器根本没办法知道客户端是程序还是人,或是一条狗。

相关文章