某不知名博客 某不知名博客
首页
  • 《vulcat文档》
  • Web安全

    • 《BurpSuite及官方实验室》
    • 《OSWE学习历程》
  • 云原生安全

    • 《Docker命令大全》
    • 《CKS考试学习指南》
    • 《旧-Kubernetes教程》
漏洞库
  • 《渗透工具大全》
  • 《云安全》
事件库
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Carsaid

安全界的小学生
首页
  • 《vulcat文档》
  • Web安全

    • 《BurpSuite及官方实验室》
    • 《OSWE学习历程》
  • 云原生安全

    • 《Docker命令大全》
    • 《CKS考试学习指南》
    • 《旧-Kubernetes教程》
漏洞库
  • 《渗透工具大全》
  • 《云安全》
事件库
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 前言

  • 服务器端主题(翻译)

  • 客户端主题(翻译)

  • 高级主题(翻译)

    • 高级主题
    • 不安全的反序列化

    • Web LLM攻击

    • GraphQL API漏洞

    • 服务端模板注入

    • Web缓存投毒

    • HTTP主机头攻击

    • HTTP请求走私

    • OAuth身份验证漏洞

      • OAuth身份验证漏洞
      • OAuth授权模式
        • OAuth授权模式
        • 什么是OAuth授权模式?
        • OAuth作用域
        • 授权码模式
          • 1. 授权请求
          • 2. 用户登录并同意
          • 3. 下发授权码
          • 4. 令牌访问请求
          • 5. 下发访问令牌
          • 6. API调用
          • 7. 资源授予
        • 隐式授权模式
          • 1. 授权请求
          • 2. 用户登录并同意
          • 3. 下发访问令牌
          • 4. API调用
          • 5. 资源授予
      • OpenID Connect
      • 如何防范OAuth身份验证漏洞
    • JWT攻击

    • 原型链污染

    • 基本技能

  • 扩展阅读(翻译)

  • 个人学习笔记

  • 实验室做题记录

  • BurpSuite及官方实验室
  • 高级主题(翻译)
  • OAuth身份验证漏洞
carsaid
2024-01-29
目录

OAuth授权模式

翻译

原文:https://portswigger.net/web-security/oauth/grant-types

- name: 翻译
  desc: 原文:https://portswigger.net/web-security/oauth/grant-types
  bgColor: '#F0DFB1'
  textColor: 'green'
1
2
3
4

# 1OAuth授权模式

在本节中,我们将介绍两种最常见 OAuth 授权模式的基础知识。如果你完全不熟悉 OAuth,我们建议你在完成 OAuth 身份验证 (opens new window)的实验之前,先阅读本章节。

# 2什么是OAuth授权模式?

OAuth 授权模式决定了 OAuth 流程中的确切步骤顺序。授权模式还会影响客户端应用程序在每个阶段如何与 OAuth 服务进行通信,包括如何发送访问令牌。因此,授权模式通常被称为 “OAuth 流”。

必须先将 OAuth 服务配置为支持特定的授权模式,然后客户端应用程序才能请求并启动相应的流。客户端应用程序在发送 OAuth 服务的初始授权请求中,指定要使用的授权模式。

有多种不同的授权模式,每种模式都有不同程度的复杂性 和 安全考虑因素。我们将重点关注 “授权码” 和 “隐式” 授权模式,因为它们是当下最常见的。

# 3OAuth作用域

对于任何 OAuth 授权模式,客户端应用程序都必须指定 它将要访问哪些数据,以及要执行什么类型的操作。它通过 OAuth 服务授权请求中的scope参数来实现此目的。

对于基本 OAuth,客户端应用程序可以请求所访问的数据范围,这对于每个 OAuth 服务都是唯一的。由于作用域的名称只是一个任意的文本字符串,因此不同程序之间提供的格式可能会有很大差异。有些程序甚至使用完整的 URI 来作为作用域名称,类似于 REST API 端点。例如,当请求对用户联系人列表的读访问权限时,作用域名称可能采用以下任何形式,具体取决于所使用的 OAuth 服务:

scope=contacts
scope=contacts.read
scope=contact-list-r
scope=https://oauth-authorization-server.com/auth/scopes/user/contacts.readonly
1
2
3
4

但是,当使用 OAuth 进行身份验证时,一般会使用标准化的 OpenID Connect 作用域。例如,作用域openid profile会将一组预定义的用户基本信息(例如其电子邮件地址、用户名等)的读访问权限授予给客户端应用程序。我们稍后将详细讨论 OpenID Connect (opens new window)。

# 4授权码模式

授权码模式一开始看起来很复杂,但当你熟悉了一些基础知识之后,它实际上比你想象的要简单。

简单来说,客户端应用程序和 OAuth 服务首先会使用重定向,来交换一系列基于浏览器的 HTTP 请求,这些请求将会启动 “流”。系统会询问用户是否同意该请求的访问。如果用户接受,则客户端应用程序会被授予 “授权码”。然后,客户端应用程序与 OAuth 服务交换此代码以接收 “访问令牌”,它们可以使用该令牌进行 API 调用来获取相关的用户数据。

从代码 / 令牌交换开始,期间发生的所有通信都经过安全的、预配置的反向通道,在服务器到服务器之间传输,因此对最终用户是不可见的。在客户端应用程序首次向 OAuth 服务注册时,将会建立此安全通道。同一时间,还会生成一个client_secret,客户端应用程序在发送这些服务器到服务器请求时,必须使用这个client_secret来验证自己的身份。

由于最敏感的数据(访问令牌和用户数据)不会通过浏览器发送,因此这种授权类型可以说是最安全的。如果可能的话,理想情况下,服务端应用程序应该始终使用这种授权模式。

Not Found Image

# 4.11. 授权请求

客户端应用程序向 OAuth 服务的/authorization端点发送请求,请求访问特定用户数据的权限。请注意,端点的映射可能因提供商而异 - 我们的实验室使用端点/auth来实现此目的。但是,你应该根据请求中使用的参数来自行识别端点。

GET /authorization?client_id=12345&redirect_uri=https://client-app.com/callback&response_type=code&scope=openid%20profile&state=ae13d489bd00e3c24 HTTP/1.1
Host: oauth-authorization-server.com
1
2

此请求包含以下值得注意的参数,通常在查询字符串中提供:

  • client_id
    
    1

    必需参数,包含客户端应用程序的唯一标识符。该值是在客户端应用程序向 OAuth 服务注册时生成的。

  • redirect_uri
    
    1

    向客户端应用程序发送授权码时,用户的浏览器应重定向至该 URI。这也称为 “回调 URI” 或 “回调端点”。许多 OAuth 攻击都基于此参数的验证缺陷。

  • response_type
    
    1

    客户端应用程序指定期望的响应类型,从而确定它要启动哪种流。对于授权码模式,该值应为code。

  • scope
    
    1

    客户端应用程序指定要访问的用户数据子集。请注意,这些数据范围可能是由 OAuth 提供程序所设置的自定义作用域,也可能是由 OpenID Connect 规范定义的标准化作用域。我们稍后将更详细地介绍 OpenID Connect (opens new window)。

  • state
    
    1

    存储一个唯一的、不可猜测的值,该值与客户端应用程序上的当前会话绑定。OAuth 服务应该在响应中返回这个确切值以及授权码。此参数充当客户端应用程序的 CSRF 令牌,确保后续请求/callback端点的和发起 OAuth 流的是同一人。

# 4.22. 用户登录并同意

当授权服务器收到初始请求时,它会将用户重定向到登录页面,在该页面上,系统会提示用户使用 OAuth 提供程序登录其帐户。这通常是他们的社交媒体帐户。

然后,服务器会向用户展示 客户端应用程序 想要访问的数据列表。这基于授权请求中定义的作用域(数据范围)。用户可以选择是否同意此访问。

请务必注意,一旦用户批准了客户端应用程序的给定范围,只要用户仍与 OAuth 服务保持有效会话,此步骤就会自动完成。换句话说,用户第一次选择 “使用社交媒体登录” 时,他们需要手动登录并同意,但如果他们稍后重新访问客户端应用程序,他们通常只需单击一下即可重新登录。

# 4.33. 下发授权码

如果用户同意请求的访问,则用户的浏览器将被重定向至授权请求redirect_uri参数中指定的/callback端点。生成的GET请求会将授权码作为查询参数。根据配置,该请求还可能携带授权请求中指定的state参数。

GET /callback?code=a1b2c3d4e5f6g7h8&state=ae13d489bd00e3c24 HTTP/1.1
Host: client-app.com
1
2

# 4.44. 令牌访问请求

客户端应用程序收到授权码后,需要用其来交换访问令牌。为此,它会向 OAuth 服务的/token端点发送服务器到服务器的POST请求。从这时开始,所有通信都发生在安全的反向信道中,因此,攻击者通常无法进行观察或控制行为。

POST /token HTTP/1.1
Host: oauth-authorization-server.com
…
client_id=12345&client_secret=SECRET&redirect_uri=https://client-app.com/callback&grant_type=authorization_code&code=a1b2c3d4e5f6g7h8
1
2
3
4

除了client_id和授权code之外,你应该还会注意到以下新参数:

  • client_secret
    
    1

    在向 OAuth 服务注册时会分配一个密钥,客户端应用程序必须包含该密钥,来对自身进行身份验证。

  • grant_type
    
    1

    确保新端点知道 客户端应用程序 要使用的授权模式。在这种情况下,应该将其设置为authorization_code。

# 4.55. 下发访问令牌

OAuth 服务将会验证令牌访问请求。如果一切正常,服务器将会对客户端应用程序做出响应,为其下发预期作用域的访问令牌

{
    "access_token": "z0y9x8w7v6u5",
    "token_type": "Bearer",
    "expires_in": 3600,
    "scope": "openid profile",
    …
}
1
2
3
4
5
6
7

# 4.66. API调用

现在,客户端应用程序拥有了访问令牌,它终于可以从资源服务器获取用户的数据了。为此,它会向 OAuth 服务的/userinfo端点发出 API 调用。访问令牌会在Authorization: Bearer标头中提交,以证明客户端应用程序有权访问此数据。

GET /userinfo HTTP/1.1
Host: oauth-resource-server.com
Authorization: Bearer z0y9x8w7v6u5
1
2
3

# 4.77. 资源授予

资源服务器应验证令牌是否有效,以及它是否属于当前客户端应用程序。如果是,它会返回所请求的资源(基于访问令牌作用域的用户数据)。

{
    "username":"carlos",
    "email":"carlos@carlos-montoya.net",
    …
}
1
2
3
4
5

最终,客户端应用程序可以将这些数据用于其预期目的。在 OAuth 身份验证的场景下,这通常被用作一个 ID ,为用户授予经过身份验证的会话,从而有效地登录其账户。

# 5隐式授权模式

隐式授权模式要简单得多。客户端应用程序不会获取授权码,然后用其交换访问令牌,而是在用户同意之后直接获得访问令牌。

你可能想知道,为什么客户端应用程序并不总是使用隐式授权模式。答案很简单——它的安全性要低得多。在使用隐式授权类型时,所有的通信都通过浏览器重定向来进行 - 没有像授权码模式那样的安全反向通道。这意味着,敏感的访问令牌和用户数据更容易受到潜在攻击。

隐式授权模式更适合单页应用程序 和 本机桌面应用程序,因为这些应用程序无法轻松地将client_secret存储在后端,因此,这些程序在使用 授权码模式 时不会带来太大的好处。

Not Found Image

# 5.11. 授权请求

隐式流的启动方式,与授权码流大致相同。唯一的区别是response_type参数必须设置为token。

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
1
2

# 5.22. 用户登录并同意

用户登录并决定是否同意所请求的权限。此过程与授权码流完全相同。

# 5.33. 下发访问令牌

如果用户同意该请求的访问,这就是事情开始不同的地方。OAuth 服务会将用户的浏览器重定向至授权请求中指定的redirect_uri。但是,它不会发送包含授权码的查询参数,而是直接将访问令牌和其他特定于令牌的数据作为 URL 片段发送。

GET /callback#access_token=z0y9x8w7v6u5&token_type=Bearer&expires_in=5000&scope=openid%20profile&state=ae13d489bd00e3c24 HTTP/1.1
Host: client-app.com
1
2

(译者加:URL 片段是指#后面的锚点数据)

由于访问令牌是在 URL 片段中发送的,因此,令牌永远不会直接发送给客户端应用程序。相反,客户端应用程序必须使用合适的脚本来提取片段并存储它。

# 5.44. API调用

客户端应用程序成功从 URL 片段中提取访问令牌之后,可以对 OAuth 服务的/userinfo端点发出 API 调用。与授权码流不同,这种调用也可以通过浏览器进行。

GET /userinfo HTTP/1.1
Host: oauth-resource-server.com
Authorization: Bearer z0y9x8w7v6u5
1
2
3

# 5.55. 资源授予

资源服务器应验证令牌是否有效,以及它是否属于当前客户端应用程序。如果是,它会返回所请求的资源(基于访问令牌作用域的用户数据)。

{
    "username":"carlos",
    "email":"carlos@carlos-montoya.net"
}
1
2
3
4

最终,客户端应用程序可以将这些数据用于其预期目的。在 OAuth 身份验证的场景下,这通常被用作一个 ID ,为用户授予经过身份验证的会话,从而有效地登录其账户。

学习更多

现在,你已经对不同流程的工作原理有了更多的了解,你应该能够阅读我们的学习材料,来了解如何利用基于 OAuth 的身份验证机制中的漏洞。

OAuth 身份验证漏洞 (opens new window)

编辑 (opens new window)
OAuth身份验证漏洞
OpenID Connect

← OAuth身份验证漏洞 OpenID Connect→

最近更新
01
API测试笔记
04-30
02
msfvenom
03-29
03
Metasploit
03-29
更多文章>
Theme by Vdoing | Copyright © 2023-2024 Carsaid | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式