Web安全学院
Web安全学院
  • 首页
  • 译序
  • 学习路线
  • 前篇
    • Web应用程序安全测试
    • 动态应用程序安全测试(DAST)
    • 带外应用程序安全测试(OAST)
  • 服务器端主题
    • SQL注入
      • SQL注入
      • SQL注入UNION攻击
      • 在SQL注入攻击中检索数据库
      • SQL盲注
      • SQL注入速查表
    • 认证
      • 认证漏洞
      • 基于密码登录中的漏洞
      • 多因素认证中的漏洞
      • 其他认证机制中的漏洞
      • 如何保护你的认证机制
    • 目录遍历
      • 目录遍历
    • 命令注入
      • OS命令注入
    • 业务逻辑漏洞
      • 业务逻辑漏洞
      • 业务逻辑漏洞示例
    • 信息泄露
      • 信息泄露漏洞
      • 如何发现并利用信息泄露漏洞
    • 访问控制
      • 访问控制漏洞与权限提升
      • 不安全的直接对象引用(IDOR)
      • 访问控制安全模型
    • 文件上传漏洞
      • 文件上传漏洞
    • 条件竞争
      • 条件竞争
    • 服务器端请求伪造(SSRF)
      • 服务器端请求伪造(SSRF)
      • 盲SSRF漏洞
    • XXE注入
      • XML外部实体(XXE)注入
      • XML实体
      • 发现并利用盲XXE漏洞
  • 客户端主题
    • 跨站脚本(XSS)
      • 跨站脚本
      • 反射型XSS
      • 存储型XSS
      • 基于DOM的XSS
      • XSS上下文
        • 跨站脚本上下文
        • 客户端模版注入
      • 利用跨站脚本漏洞
      • 内容安全策略
      • 悬空标记注入
      • 如何防范XSS漏洞
      • 跨站脚本(XSS)速查表
    • 跨站请求伪造(CSRF)
      • 跨站请求伪造(CSRF)
      • XSS与CSRF
      • 绕过CSRF令牌验证
      • 绕过SameSite Cookie限制
      • 绕过基于Referer的CSRF防御
      • 如何防范CSRF漏洞
    • 跨域资源共享(CORS)
      • 跨域资源共享(CORS)
      • 同源策略(SOP)
      • CORS和Access-Control-Allow-Origin响应标头
    • 点击劫持
      • 点击劫持(UI伪装)
    • 基于DOM的漏洞
      • 基于DOM的漏洞
      • 控制Web消息源
      • 基于DOM的开放重定向
      • 基于DOM的Cookie操纵
      • 基于DOM的JavaScript注入
      • 基于DOM的document-domain操纵
      • 基于DOM的WebSocket URL投毒
      • 基于DOM的链接操纵
      • Web消息操纵
      • 基于DOM的Ajax请求标头操纵
      • 基于DOM的本地文件路径操纵
      • 基于DOM的客户端SQL注入
      • 基于DOM的HTML5 Storage操纵
      • 基于DOM的客户端XPath注入
      • 基于DOM的客户端JSON注入
      • DOM-data操纵
      • 基于DOM的拒绝服务
      • DOM破坏
    • WebSocket
      • 测试WebSocket安全漏洞
      • 什么是WebSocket?
      • 跨站WebSocket劫持
  • 进阶主题
    • 不安全的反序列化
      • 不安全的反序列化
      • 利用不安全的反序列化漏洞
    • 测试GraphQL API
      • 测试GraphQL API
      • 什么是GraphQL?
    • 服务器端模板注入
      • 服务器端模板注入
      • 利用服务器端模板注入漏洞
    • Web缓存投毒
      • Web缓存投毒
      • 缓存设计缺陷的利用
      • 缓存实现缺陷的利用
    • HTTP Host标头攻击
      • HTTP Host标头攻击
      • 如何识别和利用HTTP Host头的漏洞
      • 密码重置投毒
    • HTTP请求走私
      • HTTP请求走私
      • 查找HTTP请求走私漏洞
      • 利用HTTP请求走私漏洞
      • 高级请求走私
        • 高级请求走私
        • HTTP/2降级
        • 响应队列投毒
        • HTTP/2专属载体
        • HTTP请求隧道
      • 浏览器驱动的请求伪造
        • 浏览器驱动的请求伪造
        • CL.0请求走私
        • 客户端异步攻击
        • 基于暂停的异步攻击
    • OAuth认证
      • OAuth 2.0认证漏洞
      • OAuth授权类型
      • OpenID Connect
      • 如何防范OAuth认证漏洞
    • JWT攻击
      • JWT攻击
      • 在Burp Suite中使用JWT
      • 算法混淆攻击
    • 原型污染
      • 什么是原型污染?
      • JavaScript原型和继承
      • 客户端
        • 客户端原型污染漏洞
        • 通过浏览器API进行原型污染
      • 服务器端
        • 服务器端原型污染
      • 预防原型污染漏洞
    • 基本技能
      • 基本技能
      • 使用编码混淆攻击
      • 在手动测试中使用Burp Scanner
Powered by GitBook
On this page
  • 什么是OpenID Connect?
  • OpenID Connect的工作原理
  • OpenID Connect 角色
  • OpenID Connect声明和作用域
  • ID Token
  • 识别OpenID Connect
  • OpenID Connect漏洞
  • 不受保护的动态客户端注册
  • 通过引用允许授权请求
  1. 进阶主题
  2. OAuth认证

OpenID Connect

在本节中,我们将提供一些关于OpenID Connect的关键背景信息,这有助于理解我们将要讨论的一些漏洞。如果你是OAuth和OpenID Connect的新手,我们建议在尝试完成基于OpenID的实验之前先阅读这一部分。

什么是OpenID Connect?

OpenID Connect扩展了OAuth协议,提供了一个专门的身份和认证层,位于基本的OAuth实现之上。它增加了一些简单的功能,能够更好地支持OAuth认证用例。

OAuth在设计之初并没有考虑到认证;它的目的是在应用程序之间对特定的资源进行授权的一种手段。然而,许多网站开始定制OAuth作为一种认证机制使用。为了实现这一点,他们通常要求读取一些基本的用户数据,如果被授权此访问权限,则假设用户在OAuth提供商那边进行了自我认证。

这些普通的OAuth认证机制远非理想。首先,客户端应用无法知道用户何时何地如何对用户进行认证。由于这些实现都是一种自定义的变通方法,因此也没有标准的方法来请求用户数据。为了正确地支持OAuth,客户端应用程序将不得不为每个提供商配置单独的OAuth机制,每个提供商都有不同的端点,独特的作用域集等等。

OpenID Connect通过增加标准化的、与身份相关的功能,使通过OAuth进行的认证以一种更可靠和统一的方式进行,从而解决了很多问题。

OpenID Connect的工作原理

OpenID Connect可以很好地融入正常的OAuth流中。从客户端应用的角度来看,主要的区别在于有一组额外的、标准化的作用域,对于所有的提供商都是如此,以及还有一个额外的响应类型:id_token。

OpenID Connect 角色

OpenID Connect的角色与标准OAuth的角色基本相同。主要区别在于规范使用的术语略有不同。

  • 依赖方 - 请求用户认证的应用。这与OAuth客户端应用是同义的。

  • 最终用户 - 正在接受认证的用户。这与OAuth资源所有者同义。

  • OpenID提供商 - 配置为支持OpenID Connect的OAuth服务。

OpenID Connect声明和作用域

术语“申明(claims)”是指在资源服务器上表示有关用户信息的key:value对。申明的一个例子可能是"family_name":"Montoya"。

与基本的OAuth不同,其作用域对每个提供商都是独一无二的,所有OpenID Connect服务都使用一套相同的作用域。为了使用OpenID Connect,客户端应用必须在授权请求中指定openid作用域。然后它们可以包括一个或多个其他标准的作用域:

  • profile

  • email

  • address

  • phone

这些作用域中的每一个都对应于OpenID规范中定义的用户声明子集的读取访问权限。例如,请求openid profile作用域将授权客户端应用对与用户身份有关的一系列声明的读取权限,如family_name、given_name、birth_date等。

ID Token

OpenID Connect提供的另一个主要附加功能是id_token响应类型。这将返回一个使用JSON web signature(JWS)签名的JWT。JWT payload包含一个基于最初请求作用域的声明列表。它还包含用户上一次被OAuth服务认证的方式和时间信息。客户端应用可以利用这一点来决定用户是否得到了充分的认证。

使用id_token主要的好处是减少了客户端应用和OAuth服务之间需要发送的请求数量,这可以提供更好的整体性能。与其需要获得访问令牌,然后单独请求用户数据,不如在用户认证后立即将包含这些数据的ID token发送给客户端应用。

ID token中传输的数据的完整性是基于JWT加密签名,而不是像OAuth那样简单地依赖一个可信的通道。出于这个原因,使用ID token可能有助于防止一些中间人攻击。然而,鉴于用于签名验证的加密密钥是通过同一网络通道(通常暴露在/.well-known/jwks.json)传输的,一些攻击仍然是可能的。

请注意,OAuth支持多种响应类型,因此完全可以接受客户端应用同时发送的基本的OAuth响应类型和OpenID Connect id_token响应类型的授权请求:

response_type=id_token token
response_type=id_token code

在这种情况下,ID token和code或访问令牌都将同时发送到客户端应用。

识别OpenID Connect

如果OpenID connect正在被客户端应用程序积极使用,这在授权请求中应该是显而易见的。最傻瓜式的检查方法是寻找强制性的openid作用域。

即使登录过程最初看起来没有使用OpenID Connect,也仍然值得检查OAuth服务是否支持它。可以简单地尝试添加openid作用域或将响应类型更改为id_token,并观察是否会导致错误。

与基本的OAuth一样,查看OAuth提供商的文档,看看是否有任何关于其OpenID Connect支持的有用信息,这也是一个好主意。还可以从/.well-known/openid-configuration标准端点访问配置文件。

OpenID Connect漏洞

OpenID Connect的规范比基本的OAuth规范要严格得多,这意味着通常不太可能出现具有明显漏洞的古怪实现。也就是说,由于它只是位于OAuth之上的一层,因此客户端应用程序或OAuth服务仍然可能受到前面所看到的一些基于OAuth的攻击。事实上,你可能已经注意到,我们所有的OAuth认证实验也都是使用OpenID Connect的。

在本节中,我们将了解OpenID Connect一些额外的功能可能带来的一些额外漏洞。

不受保护的动态客户端注册

OpenID规范概述了一种允许客户端应用向OpenID提供商注册的标准化方式。如果支持动态客户端注册,客户端应用可以通过向一个专门的/registration端点发送POST请求来注册自己。此端点的名称通常在配置文件和文档中提供。

在请求正文中,客户端应用以JSON格式提交自己的关键信息。例如,它通常需要包含一组列入白名单的重定向URI。还可以提交一系列额外信息,如想要公开的端点的名称、应用程序的名称等等。一个典型的注册请求可能看起来像这样:

POST /openid/register HTTP/1.1
Content-Type: application/json
Accept: application/json
Host: oauth-authorization-server.com
Authorization: Bearer ab12cd34ef56gh89

{
    "application_type": "web",
    "redirect_uris": [
        "https://client-app.com/callback",
        "https://client-app.com/callback2"
        ],
    "client_name": "My Application",
    "logo_uri": "https://client-app.com/logo.png",
    "token_endpoint_auth_method": "client_secret_basic",
    "jwks_uri": "https://client-app.com/my_public_keys.jwks",
    "userinfo_encrypted_response_alg": "RSA1_5",
    "userinfo_encrypted_response_enc": "A128CBC-HS256",
    …
}

OpenID提供商应要求客户端应用对自身进行认证。在上面的例子中,使用的是一个HTTP Bearer token。但是,一些提供商会允许在没有任何认证的情况下进行动态客户端注册,这使得攻击者能够注册自己的恶意客户端应用。可能会产生各种后果,具体取决于如何使用这些攻击者可控属性的值。

例如,你可能已经注意到其中一些属性可以作为URI提供。如果其中任何一个被OpenID提供者访问,就可能导致二阶SSRF漏洞,除非采取额外的安全措施。

通过引用允许授权请求

到此为止,我们已经了解了提交授权请求所需参数的标准方法,即通过查询字符串。一些OpenID提供商可以选择将这些参数以JWT的方式传入。如果支持此功能,你可以发送一个指向JSON Web Token的request_uri参数,其中包含其余的OAuth参数及其值。而根据OAuth服务的配置,此request_uri参数是 SSRF的另一个潜在向量。

你还可以使用此功能来绕过这些参数值的验证。一些服务器可能会有效地验证授权请求中的查询字符串,但可能无法将相同的验证充分应用于JWT中的参数,包括redirect_uri。

要检查此选项是否被支持,应该在配置文件和文档中查找request_uri_parameter_supported选项。或者,可以直接尝试添加request_uri参数,看看它是否有效。你会发现有些服务器支持这一功能,即使它们在文档中没有明确提到它。

PreviousOAuth授权类型Next如何防范OAuth认证漏洞

Last updated 1 year ago

实验:

通过OpenID动态客户端注册的SSRF