CSRF
CSRF 的基本概念特性
跨站请求伪造(CSRF)的是 Web 应用程序一种常见的漏洞,其攻击特性是危害性大但非常隐蔽,尤其是在大量 Web 2.0 技术的应用的背景下,CSRF 攻击完全可以在用户法毫无察觉的情况下发起攻击。国际上并未对 CSRF 攻击做出一个明确的定义,同时,攻击的发起手段方式繁多,下文会做详细介绍。可以解释的是发起的目标都是通过伪造一个用户请求,该请求不是用户想发出去的请求,而对服务器或服务来说这个请求是完全合法的一个请求,但是却完成了一个攻击者所期望的操作,比如添加一个用户到管理者的群组中,或将一个用户的现金转到另外的一个帐户中。通常开发人员对 CSRF 攻击的理解是有误区的,分为以下几方面,第一是如何攻击的,第二是危害到底在那里,第三是如何防范就才是一个完整的解决方案。本文就是要对这些基本的问题做一个详细的阐述,并且给出检测的有效方法。
CSRF 的危害实例
大部分网站往往对脚本注入有严格的防范,但是对 CSRF 的防范做的就差很多。
实例 1:假设某网站高级会员会享有某些特殊权限。而当一个普通用户付款完毕就可以让管理员将自己升级为高级会员。假设管理员将一个普通用户升级为高级会员的请求是:
http://www.mysite.com/promoteUser.jsp?username=aaaaa |
我们再假设普通用户有在网站某个论坛发表话题的权限,这样一个普通用户可以将这个 URL 发表在某些话题之中,然后用我们称为社会工程学的方法引诱网站管理员点击这个链接。当管理员点击这个链接时,这个请求就会从浏览器发送到后台服务器,从而完成身份的升级。当然,在实际攻击过程中,有很多手段使得让管理员不点击也能发送这样的请求,比如将这个 URL 设置为某个图片的源。
实例 2:以一个二手跳蚤市场为例子,比如某商业交易网站注册用户 Hacker01 和 Customer01。Hacker01 在上交易频道摆上 1 辆 9 成新的宝马,投标价格是 20000$,另外再摆上另外一量废旧车型标价 1000$,然而网站是允许加载图片显示车的状况的。所以宝马车主可以上载一个自己的图片,废旧车主也可以上载一个自己的图片。
宝马图片 url:http://myrepository/BMW.jpg car id 100000001
废旧车图片 url:http://myrepository/oldCar.jpg car id 100000002
而该拍卖网站是通过投标决定车的最终价格,假设是竞买者参加竞买宝马的时候点击购买按钮浏览器是通过发一个 GET 请求到 http://e-bussiness-car/bid?value=20000$&carid=100000001 来提交自己的竞标价格。那么 Hacker01 则可以把废旧车图片修改为 http://e-bussiness-car/bid?value=20000$&carid=100000001(或者其他的 value 参数的数值)。
这时候的情况是:Customer01 访问宝马能看见正确的图片,并且没有任何问题。而访问废旧车发现图片是一个无法看到的图片,但当 Customer01 浏览旧车图片的时候,浏览器已经向宝马车发送了一个竞标请求。这样在用户的控制之外发出了一个合法的请求,并且被服务器接收。Hack01 可以在 Customer01 不知觉的情况下将自己的宝马车卖出。通过此例可以发现 CSRF 有着非常严重的危害性。
CSRF 的防范
CSRF 的防范机制有很多种,防范的方法也根据 CSRF 攻击方式的不断升级而不断演化。常用的有检查 Refer 头部信息,使用一次性令牌,使用验证图片等手段。出于性能的考虑,如果每个请求都加入令牌验证将极大的增加服务器的负担,具体采用那种方法更合理,需要谨慎审视每种保护的优缺点。
1. 检查 HTTP 头部 Refer 信息,这是防止 CSRF 的最简单容易实现的一种手段。根据 RFC 对于 HTTP 协议里面 Refer 的定义,Refer 信息跟随出现在每个 Http 请求头部。Server 端在收到请求之后,可以去检查这个头信息,只接受来自本域的请求而忽略外部域的请求,这样就可以避免了很多风险。当然这种检查方式由于过于简单也有它自身的弱点:
a) 首先是检查 Refer 信息并不能防范来自本域的攻击。在企业业务网站上,经常会有同域的论坛,邮件等形式的 Web 应用程序存在,来自这些地方的 CSRF 攻击所携带的就是本域的 Refer 域信息,因此不能被这种防御手段所阻止。
b) 同样,某些直接发送 HTTP 请求的方式(指非浏览器,比如用后台代码等方法)可以伪造一些 Refer 信息,虽然直接进行头信息伪造的方式属于直接发送请求,很难跟随发送 cookie,但由于目前客户端手段层出不穷,flash,javascript 等大规模使用,从客户端进行 refer 的伪造,尤其是在客户端浏览器安装了越来越多的插件的情况下已经成为可能了。
2. 使用一次性令牌,这是当前 Web 应用程序的设计人员广泛使用的一种方式,方法是对于 Get 请求,在 URL 里面加入一个令牌,对于 Post 请求,在隐藏域中加入一个令牌。这个令牌由 server 端生成,由编程人员控制在客户端发送请求的时候使请求携带本令牌然后在 Server 端进行验证。但在令牌的设计上目前存在着几个错误的方案:
a) 使用和 Session 独立的令牌生成方式。这种令牌的值和 Session 无关,因此容易被其他用户伪造。这里的其他用户指的是当前 Web 应用程序的其他用户和活跃在网络传输阶段各个设置上的监听者,这种恶意用户可能使用自己的令牌来进行替换以便达到伪造的目的。
b) 完全使用 Session 认证信息作为令牌的生成方式。这种保护方式对于保护 CSRF 是起了作用的,但是可能会造成其他危害,具体来说,如果某些 URL 或者网页被拷贝下来与其他人共享,那么这些 URL 或者拷贝下来的网页中可能会含有用户的会话信息,这种信息一旦被恶意用户获得,就能造成极大的危害。
因此,一个正确的令牌设计应该是使用 Session 信息做 Hash,用得出的哈希值来做 CSRF 的令牌。
3. 使用验证图片,这种方法的出现的作用是对于机器人暴力攻击的防止。但在 CSRF 的防范上,也有一些安全性要求比较高的的应用程序结合验证图片和一次性令牌来做双重保护。由于这种图片验证信息很难被恶意程序在客户端识别,因此能够提高更强的保护。当客户端的浏览器可能已经处于一种不安全的环境中的情况下(比如客户端的安全级别设置较低,客户端浏览器安装了不安全的插件等)。
以上给的这些只是防范 CSRF 的比较通用的一些方法,Web 开发人员可以根据自己对自己的应用程序的功能的理解来确定安全级别的要求从而选择使用不同的保护措施,也推荐在同一应用程序内部结合使用多种方法来进行保护。

浙公网安备 33010602011771号