IPBUF安全漏洞报告
English
CVE-2025-14546 CVSS 6.3 中危

CVE-2025-14546 fastapi-sso OAuth CSRF状态验证缺陷漏洞

披露日期: 2025-12-19

漏洞信息

漏洞编号
CVE-2025-14546
漏洞类型
跨站请求伪造(CSRF)
CVSS评分
6.3 中危
攻击向量
网络 (AV:N)
认证要求
低权限 (PR:L)
用户交互
需要交互 (UI:R)
影响产品
fastapi-sso

相关标签

CSRFOAuthfastapi-sso状态验证缺陷认证绕过PythonFastAPISnyk

漏洞概述

fastapi-sso是一个用于FastAPI的OAuth2 SSO库,帮助开发者快速集成各种OAuth提供商(如Google、Microsoft、Facebook等)。该产品在0.19.0之前的版本中存在严重的跨站请求伪造(CSRF)漏洞。漏洞根源在于OAuth认证流程中的state参数验证机制不完善。在标准的OAuth认证流程中,state参数用于防止CSRF攻击,服务器端应生成随机state值并与用户会话绑定,在回调时验证state的有效性。然而,该库虽然提供了get_login_url方法来生成state,但并未将state持久化存储或与用户会话关联,导致verify_and_process方法直接接受回调URL中携带的state参数而无法验证其真实性。攻击者可利用此漏洞构造恶意回调URL,诱骗受害者点击,从而将攻击者的第三方平台账号(如Google、Microsoft账号)与受害者在应用中的内部账号绑定,进而可能获取受害者的敏感信息或执行未授权操作。

技术细节

漏洞主要存在于fastapi-sso的OAuth认证回调处理流程中。在正常OAuth流程中:1) 用户发起登录请求,服务器生成随机state值并存储在用户会话中;2) 重定向用户到OAuth提供商进行认证;3) OAuth提供商回调时携带state参数;4) 服务器验证回调中的state与会话中存储的state是否匹配。fastapi-sso的问题在于:get_login_url方法虽然生成了state值,但未将其存储到session中。verify_and_process方法接收回调请求时,直接从query参数中获取state并使用,完全没有与服务器端存储的值进行比对验证。攻击者可以:1) 首先用自己的账号发起OAuth登录流程,获取合法的callback URL;2) 构造包含攻击者OAuth账号信息的恶意callback URL;3) 诱骗已登录的受害者访问该恶意URL;4) 受害者应用账户将与攻击者的第三方OAuth账号绑定;5) 攻击者利用绑定关系访问受害者数据或执行特权操作。

攻击链分析

STEP 1
步骤1
攻击者使用自己的OAuth账号(如[email protected])发起正常的OAuth登录流程,获取合法的回调URL
STEP 2
步骤2
攻击者提取回调URL中的state参数值,构造包含自己OAuth账号信息的恶意callback URL
STEP 3
步骤3
攻击者通过钓鱼邮件、社交工程等方式诱骗已登录应用的用户点击恶意链接
STEP 4
步骤4
用户点击链接后,应用调用verify_and_process方法处理回调请求
STEP 5
步骤5
由于verify_and_process直接接受URL中的state参数而不验证其真实性,攻击者的OAuth账号被成功绑定到受害者的应用账户
STEP 6
步骤6
攻击者利用绑定的OAuth账号登录应用,可能访问受害者的敏感信息、执行特权操作或进行进一步攻击

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
# Malicious OAuth Callback URL for CVE-2025-14546 # Attack Scenario: Link attacker's OAuth account to victim's internal account import urllib.parse # Step 1: Attacker initiates OAuth flow and captures the callback URL # The attacker would use their own OAuth account (e.g., [email protected]) # Step 2: Attacker constructs malicious callback URL # Original callback format: # https://victim-app.com/callback?state=RANDOM_STATE&code=AUTH_CODE # Attacker modifies and distributes this URL: malicious_state = "attacker_controlled_state_value" malicious_code = "attacker_oauth_authorization_code" victim_callback_base = "https://victim-app.com/callback" malicious_url = f"{victim_callback_base}?state={malicious_state}&code={malicious_code}" print(f"Malicious URL to send to victim: {malicious_url}") # Step 3: When victim clicks the link while logged in, # their account gets linked to attacker's OAuth account because: # - verify_and_process() accepts any state value # - No validation against server-side stored state # - Attacker's OAuth code is accepted as valid # The vulnerable code flow: """ # In fastapi-sso < 0.19.0: # 1. get_login_url (generates but doesn't store state): async def get_login_url(self, request: Request, redirect_uri: str) -> str: state = secrets.token_urlsafe(16) # State generated but NOT saved to session! params = {"state": state, ...} return self.provider.get_authorize_url(**params) # 2. verify_and_process (accepts any state without validation): async def verify_and_process(self, request: Request) -> User: code = request.query_params.get("code") state = request.query_params.get("state") # State taken directly from URL! # NO validation: if state in session matches this state user = await self.provider.get_user_from_token(code, redirect_uri) return user """

影响范围

fastapi-sso < 0.19.0

防御指南

临时缓解措施
如果无法立即升级,可采取以下临时缓解措施:1) 在应用层实现额外的CSRF防护机制,如检查Referer头或使用自定义CSRF token;2) 限制OAuth回调URL的来源,仅允许来自已知OAuth提供商的回调;3) 监控异常的OAuth绑定行为,对短时间内大量账号绑定操作进行告警;4) 考虑暂时禁用受影响版本的fastapi-sso的OAuth功能,待修复完成后再启用。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表