CVE-2025-68481
Python vulnerability analysis and mitigation

Overview

CVE-2025-68481 is a login CSRF / improper authorization vulnerability in the fastapi-users Python library, enabling a "1-click account takeover" in applications using FastAPI SSO (OAuth2). The flaw affects all versions of fastapi-users before 15.0.2 and was disclosed on December 19, 2025, via a GitHub Security Advisory. The CVSS v3.1 base score is reported as 8.8 (High) by Feedly/NVD, while the official GitHub advisory scores it 5.9 (Moderate) using a higher attack-complexity vector (GitHub Advisory, Feedly).

Technical details

The root cause (CWE-285: Improper Authorization; CWE-352: Cross-Site Request Forgery) lies in fastapi_users/router/oauth.py, where generate_state_token() is always called with an empty state_data dict, producing a JWT that contains only a fixed audience claim (fastapi-users:oauth-state) and an expiration timestamp — no per-request entropy and no session binding. On the OAuth callback, the library only verifies the JWT signature and expiration via decode_jwt(); it performs no check to correlate the state value with the browser session that initiated the flow, sets no correlation cookie, and maintains no server-side cache of issued state tokens. Because the resulting state JWT is valid for any client for approximately one hour, an attacker who obtains a server-generated state token can reuse it to force any victim's browser to complete an OAuth callback with the attacker's authorization code (GitHub Advisory, Vulnerable Source).

Impact

Exploitation enables a login CSRF attack with two possible outcomes depending on the application's UserManager implementation: the victim is silently logged into the attacker's account (session fixation), or — in applications where the UserManager links SSO identities to already-authenticated users — the attacker's OAuth account becomes permanently linked to the victim's application account, resulting in full account takeover. The impact spans confidentiality, integrity, and availability at the level of the victim's account privileges, and could facilitate lateral movement within the application if the compromised account holds elevated roles (GitHub Advisory, Feedly).

Exploitability

A proof-of-concept exploit scenario is publicly documented in the GitHub Security Advisory; no weaponized exploit kit or in-the-wild exploitation has been reported as of the disclosure date. The attack requires user interaction (victim must click a malicious link or load a crafted URL), but has low attack complexity and requires no privileges. The EPSS score is approximately 0.022% (0.000220), indicating low current exploitation probability. The vulnerability is not listed in the CISA KEV catalog (GitHub Advisory, Feedly).

Exploitation steps

  1. Initiate OAuth flow: The attacker visits the target application's /authorize endpoint (e.g., GET /auth/google/authorize) to trigger the OAuth flow and receive a server-generated state JWT.
  2. Capture the state token: The attacker intercepts or records the state parameter returned in the authorization URL redirect — this JWT is valid for ~1 hour for any client.
  3. Complete upstream OAuth with attacker's account: The attacker authenticates with the OAuth provider (e.g., Google) using their own credentials, obtaining a valid code grant tied to their provider account.
  4. Craft malicious callback URL: The attacker constructs a callback URL for the target application using their own code and the captured state token: https://target.app/auth/google/callback?code=<attacker_code>&state=<captured_state_jwt>.
  5. Trick victim into loading the URL: Via phishing, a drive-by attack, or an embedded link, the attacker causes the logged-in victim's browser to perform a GET request to the crafted callback URL.
  6. Callback is processed: Because the library only validates the JWT signature and expiration (not session binding), the callback succeeds — the attacker's OAuth identity is processed in the context of the victim's session, resulting in either the victim being logged into the attacker's account or the attacker's SSO identity being permanently linked to the victim's account (GitHub Advisory).

Indicators of compromise

  • Network: Unexpected GET requests to the OAuth callback endpoint (e.g., /auth/<provider>/callback) originating from a different IP or user-agent than the one that initiated the /authorize request; callback requests where the state JWT was issued significantly earlier than the callback timestamp.
  • Logs: Application logs showing OAuth callback completions where no corresponding /authorize request was made by the same session/cookie; multiple callback completions using the same state JWT value from different source IPs within the token's 1-hour validity window.
  • Application Behavior: Unexpected SSO account associations appearing in user records — particularly where a user's linked OAuth identity changes without the user initiating the flow; users reporting being logged into an unfamiliar account after clicking a link.

Mitigation and workarounds

Upgrade fastapi-users to version 15.0.2 or later, which implements a double-submit cookie pattern: a cryptographically random CSRF token (secrets.token_urlsafe(32)) is embedded in the state JWT and simultaneously set as an HttpOnly, Secure, SameSite=lax cookie (fastapiusersoauthcsrf); the callback handler verifies both values match using secrets.compare_digest() before processing the OAuth response (Patch Commit, GitHub Advisory). If immediate patching is not possible, interim mitigations include: adding independent CSRF protection to the OAuth callback route, implementing server-side session binding that correlates state values to specific sessions, reducing the OAuth state token expiration below 1 hour, and auditing custom UserManager implementations for unsafe SSO identity-linking logic.

Community reactions

The vulnerability was reported by security researcher David Bors (davidbors-snyk) and disclosed responsibly through GitHub's security advisory process. The fastapi-users maintainer (frankie567) published the advisory and patch on December 19, 2025. The project is noted to be in maintenance mode, with the maintainer committing to continued security updates (GitHub Repo, GitHub Advisory).

Additional resources


SourceThis report was generated using AI

Related Python vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-59714HIGH7.1
  • Python logoPython
  • cpe:2.3:a:openwebui:open_webui
NoYesAug 13, 2026
CVE-2026-48099HIGH7.1
  • Python logoPython
  • python3-wsgidav+pam
NoYesAug 13, 2026
CVE-2026-45725HIGH7.1
  • Python logoPython
  • compliance-trestle
NoYesAug 13, 2026
CVE-2026-73652HIGH7.1
  • Python logoPython
  • vantage6
NoNoAug 13, 2026
CVE-2026-45774MEDIUM6.9
  • Python logoPython
  • compliance-trestle
NoYesAug 13, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management