微软SSO集成中的顺序用户ID身份验证绕过漏洞剖析

108 阅读3分钟

身份验证绕过:微软SSO集成中的顺序用户ID漏洞 | 严重漏洞

如果你是渗透测试人员或漏洞赏金猎人,千万不要在测试中跳过SSO。这是那些人人都认为安全的功能之一,但我不断在其中发现严重缺陷。

我决定撰写本文,是因为我已经不止一次遇到同类漏洞,而且令人惊讶的是它依然存在。人们通常认为,一旦应用程序采用单点登录(特别是像微软这样的方案),身份验证就会自动变得安全。但这种假设是危险的。

在最近一次测试中,我发现登录流程表面看起来完美无缺——微软SSO、Authenticator提示,一切就位。但当我深入后端时,整个安全模型就崩溃了。服务器依赖来自客户端的可预测user_id来决定哪个账户处于活跃状态。更改该值,你突然就能以他人身份登录。

漏洞原理

该应用使用微软SSO(Azure AD)进行登录。SSO完成后,应用会颁发与用户邮箱绑定的令牌。

存在一个接受userId的API端点,服务器使用它来设置活跃账户。服务器既不验证userId是否与令牌中的已认证身份对应,也不验证MFA声明。

userId值为顺序且可枚举 → 攻击者可猜测其他用户的id并切换到其账户。

风险分析

  • 如果后端从不检查MFA声明(amr、auth_time),UI中的MFA就毫无意义。Authenticator提示的存在并不保证强制执行
  • 信任客户端提供的标识符是根本性错误。任何来自客户端的内容都必须根据经过验证的服务端声明进行验证
  • 可预测/顺序ID极易枚举,使授权检查变成可选的表演
  • 账户接管是即时发生的。一旦攻击者能在没有服务端检查的情况下更改活跃用户上下文,整个账户就会被入侵

根本原因

  • 后端信任客户端提供的状态:开发者使用来自客户端的userId作为会话/账户选择的真相来源,而不是将会话与已验证的令牌声明(sub)绑定
  • 令牌绑定逻辑薄弱:应用在SSO后颁发令牌,但从未强制执行该令牌与活跃会话之间的严格绑定
  • 加密令牌或令牌验证缺失:即使令牌被加密(JWE)或由可信IdP返回,团队有时也会跳过服务端的适当解密/验证
  • 身份验证与授权混淆:流程将"我有令牌"与"我被允许以该用户身份操作"分离
  • 遗留或匆忙的集成:快速SSO集成、演示代码或遗留路由经常复制粘贴基于id的简单逻辑并暴露给客户端
  • 可预测标识符+缺乏速率限制:使用顺序整数作为公共用户ID使枚举成本低廉

总结

SSO是一个集成方案,而非安全保证。如果你的后端哪怕稍微信任客户端输入,IdP保护就会被绕过。务必验证令牌、在服务器端强制执行MFA,并停止暴露顺序ID。