OIDC认证过程中没有判断空字符串导致的1day漏洞

远野千束技术2025/10/612 minutes1013433156 chars
Summary
|

这个bug可使用户以admin的身份进入博客后台(控制台),并且正常使用发布编辑文章,上传图片功能,具体如何触发我已邮件告诉你,请留意

以上是好心网友在发现了这个bug之后写的,以下是作者(snowykami)写的:以上变是事情的经过,不过非常感谢告知这个漏洞,十分甚至九分严重

先说问题:GitHub没有提供OIDC标准字段(不过人家是OAuth)和neo-blog的开发者(我)写的代码存在没有验证空值的问题,最终是因为我没有处理预期之外的空字符串导致的严重p0级事故

OIDC认证流程(授权码模式)

假设有web应用(neo-blog),用户浏览器,认证方(GitHub)三个角色

前置:

  • 我们需要在认证方处创建应用,配置应用的回调url,获取client_id,client_secret

  • 我们需要在应用处配置认证方的1.认证端点(authorization_endpoint),2.令牌获取端点(token_endpoint),3.用户信息端点(userinfo_endpoint),认证方提供的client_id和client_secret

在有的情况下,不一定是谁提供client_id,client_secret,两边设置一样就行,这个取决于软件和平台本身实现

  1. 首先,应用会使用身份提供者的client_idredirect_uristate创建一个可用于登录的链接给用户客户端,打开该链接会把用户引导至认证方的登录页面

  2. 用户完成身份认证,认证方会把用户重定向到应用的回调接口,该接口通过浏览器GET请求,并在查询参数中附带了认证方提供的授权码(code)和state,该web应用可以在服务端拿到这个code和state

  3. web应用服务端校验这个state是否是和之前的一致,然后使用上一步的code和预先配置的client_id,client_secret,redirect_uri作为表单参数,POST请求认证方提供的access_token端点,完成这一步可以拿到access_token

  4. 有了上一步的access_token,我们可以请求userinfo端点,获取到一个包含了用户信息的键值对map。

  5. web应用拿到认证方提供的身份信息后,就可以和自己本地的用户系统进行一系列映射、匹配和绑定,自行给用户签发token(这一步有点像你百度绑定QQ号)

问题分析

纵观整个登录流程,OIDC是一步一步来的,其中我每一步请求都有校验,出错就会响应失败。但是问题就出在最后一步,我们拿到身份信息后的步骤。GitHub的是OAuth2,由于OAuth2并没有规定用户信息端点需要返回什么东西,所以各家平台的oauth2返回的用户信息字段或多或少有点差别,而我的代码是标准的OIDC认证,OIDC基于OAuth2扩展而来,规定了用户信息端点必须返回哪些字段。比如我们认证核心就是issuer和sub字段,issuer代表签发人,一般是平台的网站,sub代表该用户在平台上的一个唯一id,就比如issuer是https://qq.com,sub是你的QQ号。

接下来就是问题的核心了,GitHub返回的issuer、email和sub字段都是空的,在经过我的结构体绑定后变成了空字符串,而我代码的逻辑如下:

  • 先根据issuer和sub进行查找,查找到绑定记录直接使用绑定用户登录

  • 如果未找到绑定记录,且当前有用户登录,那么进行账号绑定

  • 如果没有用户登录,那就用认证方提供的email字段,查找本地符合的用户进行绑

  • 如果没查到,那就创建新用户

所以不出我所意料,第一个绑定GitHub的用户就是我自己,绑定了一个空字符串id。此后有其他用户使用GitHub登录,我们结构体绑定的Sub字段依旧是空值,按照逻辑流程的第一步会用issuer和sub去查找绑定记录,issuer为https://github.com,sub为""(空字符串),很自然这个空字符串就会查找到我的那条绑定记录。导致所有使用GitHub登录的用户都会登录到第一个绑定GitHub的用户上,也就是我的管理员账户

解决方案

  • 在用户信息端点返回时进行空值检查,并单独对非标平台(例如GitHub)的用户信息字段进行重新映射,例如GitHub提供的唯一id字段是id,我们把id映射为sub。在处理完平台差异后进行issuer,sub,email字段的空值检查

  • 在数据库层的操作函数里面,加上对空值的检查,如果查询参数为空值,直接返回未找到

  • oidc登录接口新增is_bind参数来区分绑定请求和登录请求

反思

  1. 对认证流程细节把控不足:未充分考虑不同认证方返回用户信息字段的差异,过于依赖标准oidc认证逻辑,导致GitHub返回空字符串字段时,代码逻辑出现漏洞。

  2. 代码逻辑的健壮性不够:用户信息处理环节未对空字符串等异常情况进行检查,导致错误绑定和登录行为。

  3. 安全风险重视不够:未充分意识到认证逻辑错误可能带来的安全风险,未进行严格的安全审查和测试。

  4. 兼容性测试不足:未对GitHub等外部认证平台的兼容性进行充分测试,未提前了解其OAuth2认证细节并进行适配。

其实最初我觉得大平台的oauth都是标准化的,没有去看github restful api文档,现在不会这么觉得了

Copyright: OIDC认证过程中没有判断空字符串导致的1day漏洞

Posted at
10/6/2025

Unless stated otherwise, articles are licensed under CC BY-NC-SA 4.0. Please credit the source.

4 users liked
Comment (3)

Load more

关于我
S

SnowyKami

A full-stack developer.

Tags cloud
Misskey