常见的授权服务器漏洞
会话劫持
在授权码许可流程中,攻击者可以通过自己的账号登陆站点,然后篡改重定向URI将其他用户的授权码注入,访问其他受害者的资源。
解决方案:
- 客户端不能多次使用同一个授权码,如果一个客户端使用了已经被用过的授权码,授权服务器必须拒绝该请求,并且应该尽可能撤回之前通过授权码颁发的所有令牌
- 将授权码与client_id绑定,在获取令牌时做校验:保证授权码只会颁发给经过身份认证的客户端;如果客户端不是保密客户端,则要确保授权码只会颁发给请求中client_id对应的客户端
重定向URL篡改
之前已经说明在注册redirect_uri时应该尽可能具体,在授权服务器对请求中的redirect_uri与注册的redirect_uri进行校验通常有三种方法:精确匹配、允许子目录、允许子域名
精确匹配
将收到的redirect_uri参数与客户端注册信息中记录的redirect_uri进行简单的字符串比较,如果不匹配,则提示错误。精确匹配是唯一始终安全的重定向URI校验算法
允许子目录
只校验请求中redirect_uri的起始部分,只要以注册信息中的redirect_uri为起始内容,后续追加任何内容都被视为有效,redirect_uri路径可以指向注册的回调URL的一个子目录
允许子域名
为redirect_uri中的主机名部分提供了一些灵活性,如果收到的redirect_uri是注册信息中redirect_uri子域名,则会被认为有效
允许子目录的重定向攻击
OAuth客户端redirect_uri为
https://theoauthclient.com/oauth/oauthprovider/callback
OAuth客户端会发送如下请求
https://www.thecloudcompany.biz/authorize?response_type=code&client_id=CLIENT_ID@scope=SCOPE&state=STATE&redirect_uri=https://theoauthclient.com/oauth/oauthprovider/callback
确保攻击得逞的条件是,攻击者能够在目标客户端站点创建页面
https://theoauthclient.com/usergeneratedcontent/attackerpage.html
攻击者构建如下的URL
https://www.thecloudcompany.biz/authorize?response_type=code&client_id=CLIENT_ID@scope=SCOPE&state=STATE&redirect_uri=https://theoauthclient.com/oauth/oauthprovider/callback/../../usergeneratecontent/attackerpage.html
如果允许子目录的校验算法,则该redirect_uri完全合法,这个精心构造的redirect_uri使用路径遍历爬升到站点的根节点,然后再向下定位到攻击者自行生成的页面,如果授权服务器采用TOFU方法,根本不会向受害用户显示授权页面。攻击者页面内容
<html>
<h1>Autuorization in progress</h1>
<img src="https://attackersite.com">
</html>
允许子域名的重定向攻击
如果授权服务器使用允许子域名的重定向URI校验算法,并且OAuth客户端允许攻击者在redirect_uri子域名下创建受其控制的页面。攻击者控制的页面可以运行在http:attacker.theoauthclient.com之下。攻击者构建的URI如下::
https://www.thecloudcompany.biz/authorize?response_type=code&client_id=CLIENT_ID&scope=SCOPE&state=STATE&redirect_uri=https://attacker.theoauthclient.com
客户端假冒
在前面已经讨论过,可以利用重定向的漏洞获取受害者的授权码,并通过授权码获取访问令牌。决绝方案可以在授权服务器令牌端点处理授权码许可请求部分,添加如下代码
if(code.request.redirect_uri){
if(code.request.redirect_uri != req.body.redirect_uri){
res.status(400).json({Error: 'invalid_grant'});
}
}