Vulnerabilities in pkg:pypi/fastapi-users
PACKAGECVE-2025-68481 is a MODERATE (CVSS 5.9) fastapi users vulnerable to 1-click vulnerability (CWE-285: Improper Authorization) affecting Fastapi users libraries in the PyPI ecosystem. The issue involves fastapi users vulnerable to 1-click account takeover in apps using fastapi sso. Remediation is available by upgrading affected packages to version 15.0.2.
pkg:pypi/fastapi-users
Vulnerability advisories affecting package pkg:pypi/fastapi-users. Select an advisory below to view technical details or fixes.
| Advisory ID | CVE / NVD | Severity | Summary |
|---|---|---|---|
| GHSA-5j53-63w8-8625 | CVE-2025-68481 | MODERATE | FastAPI Users Vulnerable to 1-click Account Takeover in Apps Using FastAPI SSO |
CVE-2025-68481 at a Glance
Security Impact
CVSS: 5.9
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:L/A:N).
How to Fix CVE-2025-68481
To remediate this vulnerability, upgrade all affected Fastapi users dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
pip install fastapi-users>=15.0.2
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
pip show fastapi-users
How to Check if You Are Affected
To determine whether your Python environment is affected by CVE-2025-68481, inspect your installed packages using pip:
pip show fastapi-users
Analyze the terminal output to locate any version of Fastapi users in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 15.0.2), your application is affected.
Note: The pip show fastapi-users command checks currently installed packages in your active Python environment.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-285: Improper Authorization, where the product does not perform or incorrectly performs an authorization check when an actor attempts to access a resource or perform an action. In Fastapi users, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2025-68481 Affected Fastapi users Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
fastapi-users
|
PyPI |
< 15.0.2
|
15.0.2
|
References
Frequently Asked Questions
What is CVE-2025-68481?
Which Fastapi users versions are affected?
What version fixes CVE-2025-68481?
Is fastapi-users affected?
What is the CVSS score of CVE-2025-68481?
What CWE is associated with CVE-2025-68481?
How can I check PyPI dependencies for CVE-2025-68481?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-5j53-63w8-8625",
"modified" : "2025-12-20T05:46:19Z",
"published" : "2025-12-19T21:10:40Z",
"aliases" : [ "CVE-2025-68481" ],
"summary" : "FastAPI Users Vulnerable to 1-click Account Takeover in Apps Using FastAPI SSO",
"details" : "**Description**\n\nThe OAuth login state tokens are completely stateless and carry no per-request entropy or any data that could link them to the session that initiated the OAuth flow. `generate_state_token()` is always called with an empty `state_data` dict, so the resulting JWT only contains the fixed audience claim plus an expiration timestamp. \\[1\\]\n\n```py\n state_data: dict[str, str] = {}\n state = generate_state_token(state_data, state_secret)\n authorization_url = await oauth_client.get_authorization_url(\n authorize_redirect_url,\n state,\n scopes,\n )\n```\n\n*fastapi\\_users/router/oauth.py:65-71*\n\nOn callback, the library merely checks that the JWT verifies under `state_secret` and is unexpired; there is no attempt to match the state value to the browser that initiated the OAuth request, no correlation cookie, and no server-side cache. \\[2\\]\n\n```py\n try:\n decode_jwt(state, state_secret, [STATE_TOKEN_AUDIENCE])\n except jwt.DecodeError:\n raise HTTPException(\n status_code=status.HTTP_400_BAD_REQUEST,\n detail=ErrorCode.ACCESS_TOKEN_DECODE_ERROR,\n )\n except jwt.ExpiredSignatureError:\n raise HTTPException(\n status_code=status.HTTP_400_BAD_REQUEST,\n detail=ErrorCode.ACCESS_TOKEN_ALREADY_EXPIRED,\n )\n```\n\n*fastapi\\_users/router/oauth.py:130-141*\n\nAny attacker can hit `/authorize`, capture the server-generated state, finish the upstream OAuth flow with their own provider account, and then trick a victim into loading `.../callback?code=<attacker_code>&state=<attacker_state>`. Because the state JWT is valid for any client for \\~1 hour, the victim’s browser will complete the flow. This leads to login CSRF. Depending on the app’s logic, the login CSRF can lead to an account takeover of the victim account or to the victim user getting logged in to the attacker's account.\n\n\\[1\\] [https://github.com/fastapi-users/fastapi-users/blob/bcee8c9b884de31decb5d799aead3974a0b5b158/fastapi\\_users/router/oauth.py\\#L57](https://github.com/fastapi-users/fastapi-users/blob/bcee8c9b884de31decb5d799aead3974a0b5b158/fastapi_users/router/oauth.py#L57)\n\n\\[2\\] \n[https://github.com/fastapi-users/fastapi-users/blob/bcee8c9b884de31decb5d799aead3974a0b5b158/fastapi\\_users/router/oauth.py\\#L111](https://github.com/fastapi-users/fastapi-users/blob/bcee8c9b884de31decb5d799aead3974a0b5b158/fastapi_users/router/oauth.py#L111)\n\n**Proof of Concept**\n\nLet’s think of an app \\- AwesomeFastAPIApp. Let’s assume that the AwesomeFastAPIApp has internal logic that uses a `UserManager` different from the default `BaseUserManager.` With this `manager,` when an already logged-in user performs a callback request, the newly provided SSO identity gets linked to the already existing user that made the request.\n\nThen, an attacker can get account takeover inside the app by performing the following actions:\n\n1\\. They start an SSO OAuth flow, but stop it right before making the callback call to AwesomeFastAPIApp; \n2\\. The attacker tricks a logged-in user (via phishing, a drive-by attack, etc.) to perform a GET request with the attacker's state value and grant code to the AwesomeFastAPIApp callback. Because the library doesn’t check whether the state token is linked to the session performing the callback, the callback is processed, the grant code is sent to the provider, and the account linking takes place.\n\nAfter the GET request is performed, the attacker's SSO account is linked with the victim's AwesomeFastAPIApp account permanently.\n\n**Suggested Fix**\n\nMake the state a value tied to the session of the user that initiated the OAuth flow, as recommended by the official RFC. \\[3\\]\n\n\n\\[3\\] [https://www.rfc-editor.org/rfc/rfc6749\\#section-10.12](https://www.rfc-editor.org/rfc/rfc6749#section-10.12)",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:L/A:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "PyPI",
"name" : "fastapi-users"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "15.0.2"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/fastapi-users/fastapi-users/security/advisories/GHSA-5j53-63w8-8625"
}, {
"type" : "ADVISORY",
"url" : "https://nvd.nist.gov/vuln/detail/CVE-2025-68481"
}, {
"type" : "WEB",
"url" : "https://github.com/fastapi-users/fastapi-users/commit/7cf413cd766b9cb0ab323ce424ddab2c0d235932"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/fastapi-users/fastapi-users"
}, {
"type" : "WEB",
"url" : "https://github.com/fastapi-users/fastapi-users/blob/bcee8c9b884de31decb5d799aead3974a0b5b158/fastapi_users/router/oauth.py#L111"
}, {
"type" : "WEB",
"url" : "https://github.com/fastapi-users/fastapi-users/blob/bcee8c9b884de31decb5d799aead3974a0b5b158/fastapi_users/router/oauth.py#L57"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-285", "CWE-352" ],
"severity" : "MODERATE",
"github_reviewed" : true,
"github_reviewed_at" : "2025-12-19T21:10:40Z",
"nvd_published_at" : "2025-12-19T21:15:54Z"
}
}