OAuth 2.0系列(七)--- OAuth 2.0可能存在的安全漏洞及预防方法

本文将梳理一下OAuth 2.0中客户端、授权服务器和资源服务器上可能被利用的漏洞以及预防方法。

一、客户端漏洞及预防方法

对于客户端来说,最重要的信息就是客户端密钥和令牌,所以客户端上能够被利用的漏洞就是令牌和密钥失窃。

1.1 针对客户端的CSRF攻击

CSRF:cross-site request foregry,跨站请求伪造,在OAuth 2.0中的体现就是攻击者伪造一个合法的请求,并让完成身份认证的正常用户触发该请求,以达到窃取用户令牌的目的。详细流程可以用下面的图表示

OAuth 2.0系列(七)--- OAuth 2.0可能存在的安全漏洞及预防方法

 

      如上图所示,攻击者发起攻击的前提是被攻击对象在授权服务器上完成了身份认证和授权,这样当用户无意中点击攻击者伪造的请求之后,以个人名义向授权服务器请求token(但是用户无感知),因为令牌是授权服务器针对客户端颁发的,授权服务器无法知道接收到的授权码是攻击者的还是正常用户的,因为请求来自正常用户,所以授权服务器只能给正常用户颁发令牌,但在响应结果中获取到令牌的是攻击者而非正常用户,当攻击者拿到令牌之后,就会向资源服务器请求正常用户的资源了!!!

      来分析一下这个漏洞出现的原因:上图中的攻击者和被攻击者,对于授权服务器和客户端来说都是正常的用户,只要用户能完成给客户端授权的操作,他们都能通过客户端请求受保护的资源,而授权是否成功的结果是能否拿到授权码,当他们都完成了认证授权后都能拿到授权码,而且这个授权码只是用户和客户端之间的唯一标识,授权服务器不会区分授权码是哪个用户的请求,因为请求都来自客户端而非用户,所以就会出现这样一种情况:任何用户都能拿着别人的授权码向授权服务器请求令牌,而这个令牌却是自己的,反过来也是如此,攻击者正是利用了这一漏洞,使用自己的授权码伪造获取令牌的请求,并且想办法让用户在不经意间触发请求从而获取用户的令牌,想来真是妙啊!!!

      既然知道了自己的软肋,那是否有办法搞个盔甲预防这种攻击呢?答案是肯定的!既然任何人都能使用自己的授权码请求别人的令牌,而且授权服务器无法区分请求令牌的授权码是不是真正的用户,那客户端就要想办法在请求令牌之前检查这个授权码是否是这个用户完成授权之后授权服务器返回的,这点对于客户端来说就是小菜一碟了,因为只有它能将用户和授权码关联起来,方法就是前面提到的state参数,这个参数看似不起眼,实则大有可用,因为它就是客户端的盔甲!OAuth核心规范中对state参数是这样描述的:

客户端用来维持请求与回调之间状态的不透明值。授权服务器将用户代理重定向回客户端时包含该值。应该使用这个参数,它可以防止CSRF跨站请求伪造。

 为了预防CSRF攻击,在将用户重定向至授权服务器之前,客户端会生成一个请求上下文标识state,并将state一起发送到授权服务器上,授权服务器完成用户的认证授权后,回传state和授权码,客户端接收到回调请求后,需要校验是否有state参数,以及state是否是当前用户的上下文,如果不是则直接报错,这样一来就轻松地解决了当前用户的授权码被替换的问题,实现起来其实并不复杂,但是容易忽略!!!

1.2 客户端凭据失窃

      客户端凭据失窃是针对隐式许可类型而言的,因为在有客户端的后端信道中,客户端的密钥是存储在客户端服务器的,正常来讲还是相对安全,但是在客户端和用户为一体的浏览器应用中,客户端密钥是存储在浏览器中的,这存在很大的密钥失窃风险,一旦密钥失窃,就意味着任何人都能盗取自己令牌,类似账号被盗!

       解决方法:使用动态注册客户端。动态注册客户端是指不提前分配client_id和client_secret给客户端,当客户端需要使用client_id和client_secret时,先检查客户端是否存在,不存在时向授权服务器请求注册!

1.3 客户端重定向URI注册

客户端重定向URI注册,是指利用授权服务器重定向到客户端注册时提供的重定向地址进行的攻击,主要有以下两种:授权码失窃和令牌失窃。其实无论何种攻击,盗取用户的令牌进行为所欲为是攻击者的最终目的,盗取到授权码之后,可以利用CSRF攻击进一步盗取用户的令牌,可谓是步步惊心,下面来看看这两种攻击都是怎么发生的!

1.3.1 授权码失窃 

授权码失窃主要是利用HTTP请求的Referer头。HTTP Referrer(据说当初被错误的拼写成Referer,沿用至今

上一篇:OAuth 2.1 的进化之路


下一篇:有关OAuth 2.0简化模式中步骤D-F的解释