Make Redirection Evil Again: URL Parser Issues in OAuth

  • A+
所属分类:安全文章
摘要

from:bh-asia-Wang-Make-Redirection-Evil-Again自2012年以来,OAuth 2.0已被全球各地的在线服务提供商广泛部署。此后,与OAuth相关的安全问题不时被曝光,并且,其中的大多数问题是由协议的实现中的安全问题所致。对于OAuth标准来说,其中的用户代理重定向机制是认证授权过程中的一个相对薄弱环节,因为开发人员和运维人员很难正确地认识、理解和实现所有细微而关键的各种需求。在本文中,我们首先回顾安全社区了解OAuth重定向威胁的历程,并介绍OAuth规范的发展过程,以及针对当前版本的最佳实践。然后,我们将为读者介绍一种新型的OAuth重定向攻击技术,该技术能够通过主流浏览器和移动应用程序中的重定向处理方式来利用URL解析漏洞。特别是,某些攻击利用了我们在主流浏览器或Android平台中最新发现的URL解析漏洞(后者是被独立发现的,并且目前该漏洞已被修复)。我们对全球50家OAuth服务提供商进行的实证研究表明,拥有10,000多个OAuth客户端应用程序和数百万终端用户的众多顶级提供商都容易受到这种高危漏洞的影响。特别是,攻击者能够利用这种漏洞劫持第三方应用程序帐户,获取敏感私人信息的访问权限,甚至能够冒充受害者来执行特权操作。

from:bh-asia-Wang-Make-Redirection-Evil-Again

0x00 摘要

自2012年以来,OAuth 2.0已被全球各地的在线服务提供商广泛部署。此后,与OAuth相关的安全问题不时被曝光,并且,其中的大多数问题是由协议的实现中的安全问题所致。对于OAuth标准来说,其中的用户代理重定向机制是认证授权过程中的一个相对薄弱环节,因为开发人员和运维人员很难正确地认识、理解和实现所有细微而关键的各种需求。在本文中,我们首先回顾安全社区了解OAuth重定向威胁的历程,并介绍OAuth规范的发展过程,以及针对当前版本的最佳实践。然后,我们将为读者介绍一种新型的OAuth重定向攻击技术,该技术能够通过主流浏览器和移动应用程序中的重定向处理方式来利用URL解析漏洞。特别是,某些攻击利用了我们在主流浏览器或Android平台中最新发现的URL解析漏洞(后者是被独立发现的,并且目前该漏洞已被修复)。我们对全球50家OAuth服务提供商进行的实证研究表明,拥有10,000多个OAuth客户端应用程序和数百万终端用户的众多顶级提供商都容易受到这种高危漏洞的影响。特别是,攻击者能够利用这种漏洞劫持第三方应用程序帐户,获取敏感私人信息的访问权限,甚至能够冒充受害者来执行特权操作。

0x01 背景知识

OAuth 2.0

RFC 6749给出了OAuth 2.0授权框架的详细刻画,作为OAuth 1.0的替代规范,OAuth 2.0当前已经成为最流行的授权框架。下面,我们先介绍与该框架有关的术语,然后通过两个广泛实现的授权方式来帮助读者理解该协议,即授权码(图1)和隐式(图2)授权方式。

Make Redirection Evil Again:  URL  Parser Issues in OAuth

                    1.基于机密客户端的OAuth 2.0授权码授权方式 

图1展示了基于机密客户端的授权码授权方式。虽然OAuth 2.0的设计初衷是用于授权,但现实中,该规范的实施和部署通常都是用于身份验证的。在不同的上下文中,OAuth服务提供商具有不同的称谓。用于授权时,服务提供商的服务器称为授权服务器(AS)。用于身份验证时,人们通常将其称为身份提供商(Identity Provider,IdP)。我们可以将IdP视为AS的特例,因为身份是AS提供的一种特殊的受保护资源。机密客户端是指OAuth客户端,它能够在保护用户凭证的情况下向提供商证明其身份,这意味着客户端需要部署在服务器端。

相对而言,无法保护用户凭证的客户端是公共客户端。

图1中所示的授权方式涉及以下步骤:

  1. 用户访问托管OAuth客户端的网络服务器,例如IMDB网站,并通过例如点击“Connect with Facebook”按钮等方式启动OAuth授权过程。
  2. Web服务器生成一个会话绑定的变量state,用于防止CSRF攻击,同时返回一个包含重定向的响应。
  3. 重定向与必要参数一起发送给AS。response_type参数设为“code”,表示使用授权码。OAuth客户端使用client_id来标识自己。redirect_uri告诉AS将结果返回到什么地方。
  4. AS对用户进行身份验证后,会向客户端返回授权码。通过重定向将授权码发送给用户代理,重定向地址是由第3步中提供的redirect_uri参数的值指定。
  5. User-agent处理重定向,并使用向OAuth客户端发送请求,其中含有授权码和state。在接受请求之前,客户端需要验证当前state变量的值是否等于第2步中发出的state变量的值。
  6. 机密客户端交换access_token的授权码。client_secret用于向AS证明客户端的身份。这里还提供了redirect_uri参数,该参数是预定义的重定向端点。
  7. 授权服务器(AS)对客户端进行身份验证,验证请求中的redirect_uri是否与第3步中收到的redirect_uri一致。然后,AS将access_token返回给客户端,这样,客户端就可以使用这个令牌访问受保护的资源了。

Make Redirection Evil Again:  URL  Parser Issues in OAuth

                    2.使用公共客户端的OAuth 2.0隐式授权方式 

在图2中,公共客户端使用的是隐式授权方式。与图1相比,这个过程更加简单,但是,这是以牺牲安全性为代价的。由于客户端是公开的,无法向提供商进行身份验证,因此存在客户端被冒充的风险。这两种授权方式的主要区别在于,发送授权请求之后没有返回中间性质的code参数,而是直接使用URL锚点(格式为https://client.tld/callback#access_token)返回了一个包含access_token的重定向。当重定向时,该URL锚点由用户代理保存,而不是根据RFC 2616[1]的规定通过请求进行发送。然后,服务器会返回一个网页,并使用Javascript提取出access_token,这样就可以直接使用了。

适用于原生应用的OAuth 2.0

RFC 8252 [2]建议将OAuth 2.0用作本机应用程序的最佳实践,例如移动应用程序和桌面应用程序。虽然原始OAuth 2.0(根据RFC 6749 [3])是一个通用框架,其中包含使用本机应用程序作为客户端的情景,但是某些本机应用程序所特有的功能,可能带来新的安全威胁,而这些都是原始版本中没有考虑到的情况。

Make Redirection Evil Again:  URL  Parser Issues in OAuth

                    3.本机应用程序的OAuth 2.0流程 

图3是RFC 8252建议的本机应用程序OAuth 2.0认证授权的简化流程图。这里关注的重点是用于将授权码传递给本机应用程序的重定向机制。在第4步中,当浏览器处理指向具有自定义scheme的URL的重定向时,将调用注册了该scheme的本机应用程序。请注意,根据文献[4]和[5]中的介绍,OAuth 2.0的实现实际上有许多变体。例如,当使用服务器端的机密客户端时,第5和6步将被替换为从本机应用程序向服务器端的OAuth客户端发送授权码请求。而在其他的实现中,则使用嵌入式用户代理(例如,WebView)或其他外部用户代理(例如,其他移动应用程序)来代替浏览器。不过,由于本文的焦点是重定向机制,而它存在于所有这些变体中,所以,这里不对这些变体进行区分,并假设我们讨论的对象使用如图3所示的模型。

URL语法简介

第一个URL(统一资源定位符)标准是IETF协会于1994年发布的RFC 1738 [6]。后来,2005年发布的RFC 3986 [7]发展为更加通用的URI(统一资源标识符)标准。但是,IETF并不是维护URL规范的唯一组织。2005年,WHATWG也推出了自家的URL规范[8],该规范更侧重于浏览器。虽然两种之间的区别很小,但正是这些微小的区别,最终导致了本文讨论的URL解析器安全隐患。由于我们的主要目标是攻击OAuth,所以,我们并不会深入研究URL解析器规范的细节,相反,我们将使用WHATWG 组织当前的URL标准作为参考,来介绍URL的一些必要背景知识。之所以选择它,一方面是它的更新程度更高,另一方面它使用状态机为解析器给出了一个更明确的定义 ,同时,大多数现代浏览器都遵循该标准。

Make Redirection Evil Again:  URL  Parser Issues in OAuth

                    4URL的组成部分 

图4显示了一个完整URL的所有组件。由于我们在本文中介绍的威胁主要与Scheme和Authority组件相关,因此本节不讨论其他组件。请注意,下面的描述可能并不准确,请参阅规范以获得严格的定义。

  • Scheme:以[a-zA-Z]开头,可以包含[a-zA-Z0-9+-.],用于标识URL的类型。
  • Authority:这是最复杂也是最容易出现问题的组件。这里需要注意以下几点:(a)除了最后一个@之外,user-info中的所有特殊字符都是URL编码的。(b)在特殊scheme中,例如HTTP和FTP协议,/被视为路径分隔符,其用途与/相同。(c)对于/、/、#和?这四个字符来说,第一个出现在URL中的那个字符,将被视为权限之间的分隔符,而不管它位于哪个组件中。

0x02 OAuth的重定向漏洞史

时间线

  1. 2012年12月。在RFC 6749——“The OAuth 2.0 Authorization Framework”[3]中,介绍了重定向URL操纵漏洞及其缓解措施,详情请参阅10.6小节。为了防止这种攻击,AS应该执行两个验证操作:Validation-1和Validation-2。
        Validation-1:授权服务器必须确保用于获取授权码的重定向URL与使用授权码获取访问令牌时提供的重定向URL相同     Validation-2:如果请求中提供了重定向URL,授权服务器必须根据注册值对其进行验证。 

值得注意的是,第二个要求没有指定如何“验证”重定向URL。

  1. 2013年1月。RFC 6819——“ OAuth 2.0 Threat Model and Security Considerations”[9]指出:授权服务器应该要求所有客户端注册其“redirect_uri”,并且“redirect_uri”应该是完整的URL。此外,在#4.4.1小节中,讨论了在不同的授权码窃取场景中,针对不同授权码注入攻击的对策,注意这里没有涉及重定向URL。

  2. 2014年2月。在“OpenID Connect Core 1.0 ”[10]中,它明确要求使用RFC 3986 [7]中定义的简单字符串比较方法来验证redirect_uri。

  3. 2014年5月。某研究人员针对被其命名为隐蔽重定向的安全漏洞发布了一个网站[11]和相关POC视频,并引起了媒体的关注。很快,包括OAuth规范作者之一在内的研究人员指出,这种威胁并不是一种新型威胁,并且已经被涵盖在规范中了[12]。

  4. 2017年5月。“ OAuth 2.0 Security Best Current Practice”[13]的初稿发布。从这里开始,重定向URL验证成为重点关注对象,并强调AS应该使用简单的字符串比较方法,因为正确实现模式匹配过于复杂。

OAuth供应商的反应

在2014年之前,许多OAuth供应商使用域白名单或模式匹配来验证重定向URL。在隐蔽重定向漏洞引起大众关注之后,出现了一系列的相关漏洞报告,因此,供应商开始修改其OAuth实现,以消除URL模式匹配所隐藏的风险。但是,正如一些供应商所说,考虑到向后兼容性问题,这将是一个非常漫长的过程。

在2015年3月,Paypal发布了一个安全更新,要求开发人员更新redirect_uri配置以使用完整的URL [14]。这实际上就是在强制使用严格的URL匹配方法和过时的模式匹配方法。

2017年12月,Facebook提供了一个名为Strict URL Matching的新选项,后来,该选项被默认打开[15]。在此之前,使用的是前缀匹配方法,并且如果没有配置重定向URL的话,则客户端域下的任何URL都是被允许的。

2018年2月,QQ发布了一条通知,要求开发人员将redirect_uri配置改为完整的URL,而不仅仅是域[16]。在此之前,QQ正在使用域匹配进行redirect_uri验证。实际上,从2014年到2016年,在隐蔽重定向漏洞曝光之后的两年中,有几个漏洞正是钻了验证宽松的空子。

0x03 相关文献

利用依赖方(relying party)网站上的信息泄露端点来窃取OAuth授权码/令牌是一种古老的攻击技术。文献[11]中讨论的重定向就是这种类型攻击技术中最著名的一种。攻击者需要在依赖方的网站上找到一个开放式重定向(Open Redirect)漏洞来发动攻击。另一个例子是Egor Homakov [17]报告的Github OAuth漏洞,该漏洞是加载跨域资源时Referer头部中的授权码/令牌泄漏所致。由于这些攻击都需要利用依赖方网站上的漏洞,因此,部分OAuth供应商(如微软[18])拒绝解决他们在这方面的安全问题。相比之下,本文讨论的URL解析器相关攻击则是OAuth供应商方面的漏洞,因此,该漏洞肯定会影响所有依赖方网站,并且不依赖于任何其他漏洞。简而言之,我们的URL解析器相关攻击方法,不仅攻击范围更广,而且利用方法也更简单粗暴。关于这种类型漏洞的在野利用已经出现过几篇报告,[19] [20]通过在域中添加后缀来利用不够严谨的URL验证器,而[21] [22]则利用了供应商的URL解析器漏洞,[23] 甚至利用了Internet Explorer 11的URL解析漏洞。在我们的研究过程中,对这种威胁进行了全面的探索,并引入了一些新颖的攻击技术,并曝光了一些新型浏览器漏洞。同时,我们开辟了针对移动设备的WebView Redirector OAuth攻击的先河。与文献[24]介绍的移动设备中的覆盖重定向URL漏洞(需要安装恶意应用程序)相比,我们的攻击方案的优势在于,利用的是现成的移动应用程序以及两个不太知名的Android URL解析器漏洞——这些漏洞已隐藏多年,并且直到最近才刚得到修复。

0x04 新型威胁及其利用方法

URL验证器常用模式

我们在对现实世界中的OAuth实现进行大规模评估期间注意到,OAuth供应商的URL验证器的行为方式是并不相同。在本节中,将为读者介绍最常见的URL验证器行为,并在下一节中讨论了针对每种行为的漏洞利用技术。

  • 域白名单

许多OAuth供应商(尤其是那些使用旧版规范的供应商)允许客户端不显式配置redirect_uri参数。他们只检查URL的域部分,并确保scheme是HTTP或HTTPs协议。其中某些供应商甚至将已配置的域的所有子域都列入白名单。在这种情况下,如果域domain.tld已列入白名单,那么https://sub.domain.tld/a/b仍为有效的重定向URL。

  • 前缀匹配

大多数OAuth供应商都要求用户注册OAuth客户端时配置redirect_uri参数。但是,有的供应商只通过前缀匹配方式来验证请求中提供的redirect_uri。在这种情况下,假设开发人员将https://domain.tld/a注册为redirect_uri,那么https://domain.tld/abc也是合法的。注意,除了进行前缀匹配之外,某些实现还会解析和验证域。

  • 任意scheme

我们发现,有的OAuth供应商虽然会对域和路径执行严格的匹配检查,但是他们却允许使用任意的自定义scheme。他们的初衷可能是让开发人员能够灵活地将OAuth用于本地应用程序。在这种情况下,则允许使用x://domain.tld/a形式的网址。

浏览器环境中的漏洞利用方法

一般而言,要想成功利用OAuth redirect_uri漏洞,首先需要找到泄漏受害者的授权码或访问令牌的方法。隐蔽重定向可以通过利用托管OAuth客户端的网站上的开放式重定向器来实现这一点,而我们关注的则是为URL验证器寻找绕过方法。换句话说,我们打破了Validation-2背后的假设。我们用于绕过URL验证器的技术的分类情况如下所示。

在本节中,URL中所有绿色文本都是主机部分。箭头(→)左侧的URL表示OAuth供应商的URL验证器的解释,而右侧的URL则表示浏览器给出的解释。

编码/解码中的安全漏洞

编码/解码技术过于复杂,因此,其中很容易出现安全漏洞,这是众所周知的。其中,参考文献“Unicode Security Guide”[25]已经对这方面的问题进行了非常深入彻底的研究,其中涵盖了许多经典的Unicode攻击技巧,这些技巧至今仍然适用。下面给出的三个攻击向量,是我们在多个实现中发现的。我们预计会出现更多基于编码/解码漏洞的攻击向量。

  • Over-consumption

如果可以使用用户凭证的话,请使用以下攻击向量进行测试:

Make Redirection Evil Again:  URL  Parser Issues in OAuth

如果允许使用子域的话,请使用以下攻击向量进行测试:

Make Redirection Evil Again:  URL  Parser Issues in OAuth

说明:当服务器中的解码器遇到超出ASCII范围的字符时,它将尝试借助Unicode字符和前导字符对其进行解码。这种漏洞在[25]中被描述为XSS攻击的一种技术。在这里,我们使用它来构建重定向漏洞。

  • 解码为问号

攻击案例1(服务器错误解码)

Make Redirection Evil Again:  URL  Parser Issues in OAuth

说明:验证域时,解析器将benign.com提取为域。在输出URL之前,服务器会将不可打印的%ff转换为?。因此,浏览器会将请求发送到attacker.com。该技巧是从文献[22]中发现的。

攻击案例2(浏览器错误解码)

Make Redirection Evil Again:  URL  Parser Issues in OAuth

说明:浏览器无法对某些格式错误的Unicode字符进行解码。于是,它将Unicode序列转换为问号(?),进而访问错误的域。该漏洞是从浏览器Edge 38.14393.1066.0中发现的。

  • 最佳匹配映射

攻击案例1:

Make Redirection Evil Again:  URL  Parser Issues in OAuth

说明:解析器保留全宽字符,而浏览器(例如某些旧版本的Edge或IE)将其规范化为半宽字符。

攻击案例2:

Make Redirection Evil Again:  URL  Parser Issues in OAuth

说明:解析器将全角字符规范化为半宽字符,而浏览器则维持全宽字符。

斜杠黑魔法漏洞

大多数浏览器都将/和/视为路径分隔符,当用户在地址栏中输入URL时,大多数浏览器会自动将/转换为/。根据URL标准[8],需要进行这种转换。但是,URL验证器和浏览器在执行这项任务的过程中有可能出问题。

  • 解析器没有将正斜杠视为路径分隔符,而浏览器则会将正斜杠视为路径分隔符。

Make Redirection Evil Again:  URL  Parser Issues in OAuth

说明:由于解析器不将/视为分隔符,所以会将benign.com作为域进行提取,而浏览器则将/转换为/,所以会将请求发送到attacker.com。

  • 解析器将正斜杠视为路径分隔符,而浏览器则不这样做。

Make Redirection Evil Again:  URL  Parser Issues in OAuth

说明:该攻击要想得手,需要借助于我们在Safari浏览器中发现并首次披露的一个新漏洞,在撰写本文时,该攻击方法对于最新版本的Safari浏览器仍然有效。处理重定向时,Safari浏览器允许在 user-info 中使用/,并且不将其视为路径分隔符。当解析器将/视为路径分隔符并将其保留到输出中时,Safari浏览器将被重定向到attacker.com。

scheme操纵漏洞

当scheme可以改为以数值开头的字符串时,则可以通过下列方式来攻击Safari浏览器:

Make Redirection Evil Again:  URL  Parser Issues in OAuth

说明:这种攻击向量基于我们首次曝光的一个Safari漏洞。根据URL规范,该scheme只能以字母开头。当重定向中的URL以数字开头时,Safari浏览器会自动在重定向地址前面添加scheme。例如,如果要重定向到https://domain.tld,那么,Safari浏览器会自动将https://添加到domain.tld前面。这导致原来的scheme即 4ttacker.com://被解释为端口为空(默认端口)的主机(4ttacker.com),而原来的主机benign.com则被解释为路径。

IPv6地址解析漏洞

Make Redirection Evil Again:  URL  Parser Issues in OAuth

说明:某些URL解析器会将[]内的字符串视为IPv6主机,并且无需进行验证。我们已将这个安全问题报告给受影响的URL解析器库的相关厂商。

组合验证器漏洞

Make Redirection Evil Again:  URL  Parser Issues in OAuth

说明:我们发现许多授权服务器对URL进行验证时,采用的是前缀匹配机制和域检测机制。假设https://benign.com被配置为redirect_uri参数的值,验证器要求输入URL必须以前面配置的值开头,同时,为了防止像https://benign.com.attacker.com这样的攻击,还需要对域进行额外的验证。不过,攻击者可以结合上面介绍的主机混淆技术来克服这些障碍。

移动应用环境中的漏洞利用方法

虽然下面的漏洞利用方法都是以Android为例进行介绍的,但是,除非明确指出相关技术是Android系统所特有的,否则,该技术同样也适用于iOS系统。

deep-link/app-link概述

在Android中,提供了两种通过URL调用应用程序的机制。其中,一种调用机制称为deep-link,即使用自定义scheme的URL,例如myapp://example.com。另一种调用机制称为app-link,即一个HTTP(S)URL,其中包含由应用程序注册的特定域。这里主要讲解deep-link,但这里介绍的方法同样适用于app-link。请注意,在iOS中,也提供了类似的链接,只是名称不同。

Android应用程序可以通过AndroidManifest.xml中的intent过滤器来注册Deeplink,具体如下所示:

<activity android:name="com.example.android.ExampleActivity"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="https" android:host="www.example.com" /> <data android:scheme="myapp" android:host="open.my.app" /> </intent-filter>

在上面的示例中,注册了两个URL,形式分别为https://www.example.com/somepathmyapp://open.my.app/somepath。请注意,BROWSABLE表示可以从浏览器访问该链接。

与上一节中讨论的浏览器环境中的攻击方法不同,对于本节中的攻击方法来说,只有当移动应用程序中包含WebView重定向器时才有效。

WebView重定向器

应用程序通常都允许通过BROWSABLE deep-link进行调用,并在WebView中加载网页。网页的地址可以是通过deep-link传递的参数,或通过其他方式传递的参数。如果没有对该地址进行相应的安全检查的话,攻击者就可以操纵该地址,并在WebView中构造一个Open Redirect。众所周知,这可能会导致某些与WebView相关的漏洞,例如使用特定配置读取本地文件,并且当应用程序以编程方式为WebView请求设置cookie/token时,还可能导致cookie/token泄漏。但是,当它被用作OAuth的攻击面时,无需借助其他漏洞,只要存在Open Redirect漏洞就足够了,并且,许多应用程序都满足这个条件。请注意,我们的攻击与RFC 7636 [26]中描述的授权码拦截攻击不同,后者需要安装恶意应用并覆盖deep-link注册。

攻击案例

案例1:移动应用中的隐蔽重定向

伪代码:

if url in deeplink.query: newUrl = deeplink.query.get("url") WebView.setHeader("X-Deeplink-From", deeplink.URL) WebView.loadUrl(newUrl) else if code in deeplink.query: OAuth.getAccessToken(deeplink.query.get("code")) else: ......

攻击向量:

Make Redirection Evil Again:  URL  Parser Issues in OAuth

绑定到myapp://deeplinkrouter/ intent过滤器的Activity将提取url参数指定的URL,并将其加载到WebView中。假设该应用程序还将myapp://deeplinkrouter/注册为OAuth redirect_uri,正常的OAuth重定向则是myapp://deeplinkrouter/?code=xxxx。这时,攻击者可以引诱受害者访问下面的链接:

Make Redirection Evil Again:  URL  Parser Issues in OAuth

AS授予相应权限并重定向到myapp://deeplinkrouter/?url=https://attacker.com&code=xxx时,将会调用注册了myapp:// deeplinkrouter/的应用程序。通过上面的伪代码的逻辑可以看出,由于url参数存在于查询中,因此,该应用程序将使用WebView加载https://attacker.com,其中deep-link含有通过自定义头部泄露的授权码。这种攻击类似于隐蔽重定向,因为可以通过操纵某个参数来发动开放式重定向攻击。但是,与浏览器不同,在WebView中加载URL时,不会保留其中的fragment部分。因此,为了使其正常工作,应用程序应设法将授权码或令牌泄露给攻击者。上面的伪代码展示的正是这种场景。

案例2:替换Scheme

伪代码:

if deeplink.host == "oauth": OAuth.getAccessToken(deeplink.query.get("code")) else if deeplink.host == "ad": ...... else: Webview.loadUrl(deeplink.URL.replace("myapp", "https"))
攻击向量:

Make Redirection Evil Again:  URL  Parser Issues in OAuth

应用程序是通过主机部分来实现deep-link的路由(route)的。如果没有匹配项,该URL将作为HTTP加载至WebView。因此,攻击者可以引诱受害者访问下面的链接:

Make Redirection Evil Again:  URL  Parser Issues in OAuth

在AS授予相应权限并重定向到带有通过移动浏览器附加了授权码的redirect_uri后,将调用该应用程序,并在WebView中加载https://attacker.com?code=xxx。

绕过主机验证

如果案例2中的应用程序将“android:host”配置为仅接受“oauth”、“ad”和“benign.com”,我们该怎么办呢?

第1种绕过方法

Make Redirection Evil Again:  URL  Parser Issues in OAuth

第2种绕过方法:

Make Redirection Evil Again:  URL  Parser Issues in OAuth

注意,如果应用程序使用net.Android.Uri解析URL的话,则这些绕过技巧也适用于案例1中的url参数。

今年早些时候,我们在测试移动应用时发现了这些漏洞。但是,我们后来发现Android已经在1月[27]和2018年4月[28]发布了这两个漏洞的补丁。不过,第1种绕过方法目前仍然奏效,因为Android URL解析器不会将/视为路径分隔符,而WebView则将其视为路径分隔符。第2种绕过方法也是有效的,因为对于Android URL来说,URL中的多个@具有混淆作用。

0x05 漏洞利用方法

授权码注入

OAuth提供了一种防止授权码被redirect_uri参数泄漏的机制。Validation-1之所以要求授权请求中的redirect_uri和令牌交换请求中的完全一致,就是为了防止这一点。这就要求AS将redirect_uri存放在授权请求中,直到令牌交换请求到来为止。我们还注意到,如果redirect_uri没有出现在令牌交换请求中,某些AS就不会验证redirect_uri。如果其客户端也未在令牌请求中提供redirect_uri,那么这种防御措施就会失效。这可以很好地解释我们观察到的结果,实际上,许多实现都容易受到授权码注入攻击。在文献[13]中也发现了这个问题,并进行了相应的介绍,同时,还给出了一些防范措施,例如nounce、授权码绑定状态以及PKCE。

作为攻击者来说,有一个简单有效的方法非常值得尝试,那就是将response_type参数的值从“code”换成“token”,并测试是否支持隐式授权方式。如此一切顺利的话,攻击者就可以直接获取access_token并绕过所有的授权码注入缓解措施。这种攻击方式由来已久,通常被称为应用程序模拟攻击,早在2014年发表的文献[29][30]中就有相关的介绍。然而,在实践中,即使在今天,这种攻击方法也是相当有效的。

利用授权码注入漏洞时,还存在一个障碍:state变量。开发人员和安全研究人员通常有一种误解,那就是绑定会话的state变量可以防御授权码注入攻击。但事实却是,只有绑定授权码的state变量才能阻止授权码注入,绑定会话的state变量只能阻止CSRF攻击。更糟糕的是,在现实中,许多用于状态验证的实现都包含安全缺陷[31]。在许多情况下,攻击者可以重用任何有效的state变量,或者通过拦截OAuth授权请求来创建有效的会话-状态对。

“盲打”(Exploit Blindly)

<html> <img src="https://provider.tld/oauth/authorize?client_id=0001&..."/> <img src="https://provider.tld/oauth/authorize?client_id=0002&..."/> <img src="https://provider.tld/oauth/authorize?client_id=0003&..."/> </html>

我们讨论的由URL解析器引起的OAuth重定向漏洞属于供应商端漏洞,这种类型的漏洞会影响供应商的所有OAuth客户端。与此同时,大多数实现都支持令牌自动同意机制:在第一次颁发令牌后,就自动给予授权的权限,这使攻击者能够发动CSRF风格的秘密攻击。最隐秘的攻击方法,是创建指向精心制作的OAuth授权URL的图像。攻击者甚至可以将这些恶意图像植入到某些在线社交平台上面。实际上,这种攻击要想得手,必须满足两个条件:

  1. 用户已登录供应商网站(AS),并且登录会话仍然有效。
  2. 没有提供“同意”页面,这通常意味着用户以前已授予客户端自动确认的权限。

对于第二个条件的情况,即客户端是否需要用户的同意,要在攻击之前获取这一信息非常困难。然而,攻击者可以在同一网页中注入数百幅图像,用来对付某个含有相关安全漏洞的供应商的所有OAuth客户端。当受害者访问网页时,所有符合第二个条件的客户端授权码/令牌将立即失窃。

0x07 结束语

结合网址解析器漏洞和OAuth重定向机制,我们发现了几种可用于截获授权码码/令牌的漏洞利用方法,并在几个流行的OAuth供应商的系统中发现了这种类型的安全漏洞。我们的评估还表明,在实践中,正确实施授权码注入缓解措施非常具有挑战性,因为供应商或客户端的实现中的安全缺陷会导致其失败。基于我们的研究,我们为开发人员的提供了如下所示的安全实现建议。

  • 对于OAuth,我们强烈建议开发人员阅读OAuth 2.0安全最佳实践草案[13],并针对自己的实现检查每种安全威胁。为了防止出现与redirect_uri相关的漏洞,效果最佳同时也是最简单的解决方案,就是使用简单字符串比较方法[6]进行URL验证。如果由于某种原因,必须使用诸如域白名单之类的模式匹配验证方式,供应商应确保Validation-1和Validation-2的实现的正确性,具体请参阅文献[13]中的第3.5.1节,它给出了授权码注入的防御措施。如果供应商使用的是URL模式匹配方法,请确保没有其他API端点/网页具有与模式匹配的URL,为此,可以让授权端点使用专用子域。
  • 对于URL解析器,我们建议开发人员尽可能直接使用流行库提供的URL解析器。如果开发人员必须自己实现URL解析器,最安全的方法是严格遵循最新的WHATWG标准。为此,需要杨哥检查涉及URL处理的所有组件,并注意编码/解码方面的安全问题。

0x08 参考资料

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: