CSRF(Cross Site Request Forgey)是排在OWASP Top10第5位的漏洞,它迫使已被认证的用户在Web系统上执行其所不欲的操作。这种攻击依赖于以下:
1) Web浏览器对会话相关信息的处理方式(如cookie或Http认证信息)
2) 攻击者对正确的Web系统的URL的了解;
3) 应用会话管理仅依赖于浏览器所了解的信息;
4) 一些HTML的tag会导致对http(s)资源的直接访问其中,前3点是确认系统是否存在该漏洞的主要前提,第4点则是用来帮助攻击者利用该漏洞的。
第1点:浏览器自动发送用于识别用户会话的信息,假设site是一个Web应用站点,victim是一个已经在该系统上经过认证的用户。在server的响应中,site发送一个带有代表victim身份的cookie给victim,原则上,一旦浏览器接收到了服务器发送的cookie,就会在后面对站点的访问中都带上这个cookie;
第2点:如果应用在URL中没有使用会话相关的信息,那就意味着应用的URL,它们的参数,相应的值可以被识别。
第3点:是指诸如cookie、或者是基于http的认证信息,存放在浏览器中后,就会包含在后面的每次请求中。
下面,我们用Get方法在做个例子,如果用户已经通过了认证,那么在他做下一次请求时,请求数据中会自动加上cookie
GET请求一般会有多种原因产生,
l 用户真正在访问Web系统;
l 用户在访问地址栏中切实敲入了URL;
l 用户点击了一个连接指向了这个URL
这些调用对于系统来说是无法区别的,特别的,第三种方式相对来说是极为危险的,有很多种方法可以用来仿造连接的真实属性,连接可以被嵌入到一封邮件中,或者在某个恶意网站上,看上去这个连接好像是在访问另一个网站,而事实上却是被引到了Web系统的访问上。如果用户点击了连接,由于它已经被系统认证通过了,浏览器就会对系统提交一个待用认证信息的GET请求。这就在系统上完成了一个操作(尽管这个操作不是用户本身所期望做的)
攻击者还可以通过Web的一些标记,注入img来达到这个目的。举个例子,假设攻击者发给用户一封邮件,引诱用户访问了一个URL,而这个URL的页面含有下面的HTML
<html><body>
...
<img src=”https://www.company.example/action” width=”0” height=”0”>
...
</body></html>
那么用户在点击这个URL时,浏览器将会做什么呢,它将会尝试显示一个宽度为0的图片,而事实上这是访问了www.company.example/action,显然如果浏览器并没有阻断下载img的图片,那么该动作就会执行了。
该问题的存在是基于以下一些事实:
l 有一些HTML的tags可能会执行一些脚本(如img)
l 浏览器本身并不能识别img这个tag里的值是否是真实合法的图片
l 不管图片是否是在网站本地或是其他网站,图片都会被下载
举个例子:
假设用户要登录到某个防火墙web管理系统,登录时,用户必须对系统进行身份验证,所以用户的会话信息会保存在cookie中。假设我们的防火墙管理系统允许认证过的用户根据防火墙规则的排号来删除规则(甚至允许用户输入“*”来删除所有的规则),那么下一步显示的就是删除页面,假定表单下面就会提交一个GET请求,是以如下的格式:
https://[target]/fwmgt/delete?rule=1
或https://[target]/fwmgt/delete?rule=*
我们举的例子很简单,仅仅是为了说明CSRF的存在,
那么,如果用户输入了“*”,然后按取了Delete键,那么就提交了如下的GET请求
https://www.company.example/fwmgt/delete?rule=*
同时就删除了所有的防火墙规则
显然,如果用户直接在地址栏中输入https://[target]/fwmgt/delete?rule=*,或者通过某个链接转接到这个url,或者如上面所说,把链接隐藏在img这个tag后面,诸如此种方法,如果用户在点击这个连接的时候,已经登录进了防火墙管理系统,显然这个访问就能成功奏效,从而达到了删除所有规则的目的。
让我们想象一下,如果这样的攻击用于一些敏感系统,竞拍系统,或者是银行转账等等,所造成的后果将会多大。
应对方法:
对于用户来说,由于CSRF漏洞极为普遍,所以在我们的日常使用中要注意以下几点:
l 保证系统使用完就注销登录的习惯;
l 不要使用浏览器的保存用户名/密码的功能,不要使用网站的“记住我”功能
l 不要使用同一个浏览器浏览普通网页和你的关键性Web系统
对于开发人员来说,如上所述,由于将会话相关的信息放入了URL才造成了上述的问题,那么如果我们在URL层面增加会话特定的信息,那么对攻击者来说就增加了了解URL结构的难度。另外,我们还可以尽可能的使用POST,而不是GET;尽可能多的增加一些诸如“你确定要这样做吗?”的页面等……
说到这,想必大家都已明白CSRF是什么了,下面我们来看下针对这个漏洞,作为测试人员该如何去测试。
一般的测试用例应该如下构建:
1. 假设u是需要被测试的URL,例如u =http://www.example.com/action;
2. 构建一个包含了访问上述URL信息的html页面;
3. 确保合法用户已经登录了系统;
4. 诱使该用户在自己不知情的情况下访问上述URL
5. 确认是否执行了该操作。