Every CVE Search/ Get API key

CVE-2026-46715

Flask-Security-Too OAuth reauthentication freshness bypass via cross- user OAuth identity acceptance

5.3 MediumFix available

Flask-Security-Too allows users to add security features to their Flask applicationa. Version 5.8.0's OAuth reauthentication flow can mark a session as fresh after verifying an OAuth account that belongs to a different user. If an attacker can operate an already-authenticated but stale victim session, they can complete OAuth verification using their own OAuth identity. The victim session is then treated as recently reauthenticated, allowing freshness-protected account actions to proceed. Version 5.8.1 contains a fix for this issue.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
Low
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
Low
Availability
None

Exploit likelihood

0.35%Up 0.3 points since Jun 12, 2026
90%50%10%1%

What each source reports

CVE List Score used 5.3

Flask-Security-Too OAuth reauthentication freshness bypass via cross- user OAuth identity acceptance

Flask-Security-Too allows users to add security features to their Flask applicationa. Version 5.8.0's OAuth reauthentication flow can mark a session as fresh after verifying an OAuth account that belongs to a different user. If an attacker can operate an already-authenticated but stale victim session, they can complete OAuth verification using their own OAuth identity. The victim session is then treated as recently reauthenticated, allowing freshness-protected account actions to proceed. Version 5.8.1 contains a fix for this issue.

Record
CVE-2026-46715
CVSS 4.0
5.3 MediumCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N
Weakness
CWE-287
Updated
2026-11-02
EUVDEUVD-2026-46039 5.3

Flask-Security-Too allows users to add security features to their Flask applicationa. Version 5.8.0's OAuth reauthentication flow can mark a session as fresh after verifying an OAuth account that belongs to a different user. If an attacker can operate an already-authenticated but stale victim session, they can complete OAuth verification using their own OAuth identity. The victim session is then treated as recently reauthenticated, allowing freshness-protected account actions to proceed. Version 5.8.1 contains a fix for this issue.

Record
EUVD-2026-46039
CVSS 4.0
5.3 MediumCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-97r5-pg8x-p63p No score

Flask-Security-Too OAuth reauthentication freshness bypass via cross- user OAuth identity acceptance

Summary

Flask-Security-Too 5.8.0's OAuth reauthentication flow can mark a session as fresh after verifying an OAuth account that belongs to a different user.

If an attacker can operate an already-authenticated but stale victim session, they can complete OAuth verification using their own OAuth identity. The victim session is then treated as recently reauthenticated, allowing freshness-protected account actions to proceed. This was reproduced against the built-in /change-username route.

Details

The issue is in the OAuth verification callback.

_oauth_response_common() resolves the OAuth provider identity to a Flask-Security user:

  • flask_security/oauth_glue.py:101-108

oauth_verify_response() then accepts any resolved user and updates the current session freshness timestamp:

  • flask_security/oauth_glue.py:182-214
  • flask_security/oauth_glue.py:201-204

The missing check is that the OAuth-resolved user must match the current authenticated session user. In the failing case:

So the attacker is not logging in as the victim, but they are satisfying the victim session's reauthentication requirement with a different account.

PoC

Tested version:

  • Flask-Security-Too 5.8.0
  • tag 5.8.0
  • commit 08288dff6907e413d848a16aaf43fc2c2b2a3b72

Used a minimal Flask app with:

SECURITY_OAUTH_ENABLE = True
SECURITY_OAUTH_BUILTIN_PROVIDERS = ["github"]
SECURITY_FRESHNESS = timedelta(seconds=1)
SECURITY_FRESHNESS_GRACE_PERIOD = timedelta(seconds=0)
SECURITY_USERNAME_ENABLE = True
SECURITY_CHANGE_USERNAME = True

The OAuth provider was replaced with a localhost mock provider
returning [email protected]. This avoids hitting a live third-party
provider while still exercising Flask-Security-Too's real OAuth
verification handler.

Reproduction steps:

1. Log in as [email protected].
2. Wait until the session is no longer fresh.
3. Confirm POST /change-username is blocked with 401 and
   reauth_required=true.
4. Start OAuth verification with POST /login/oauth-verify-start/
   github.
5. Complete the callback with an OAuth identity for
   [email protected].
6. Confirm the session is still for [email protected], but fs_paa has
   been updated.
7. Retry POST /change-username.
8. The victim user's username is changed successfully.

Observed result:

{
  "pre_bypass_status": 401,
  "pre_bypass_reauth_required": true,
  "attacker_identity": "[email protected]",
  "oauth_verify_response_status": 302,
  "post_bypass_change_username_status": 200,
  "final_email": "[email protected]",
  "final_username": "victimowned1777878574",
  "direct_impact_verified": true
}

Note: CSRF was disabled in the local harness only to keep the test
focused on the reauthentication check. This is not a CSRF bypass
report.

This bypasses Flask-Security-Too's freshness/reauthentication
boundary.

Applications using OAuth verification together with freshness-
protected account operations may allow a stale victim session to be
refreshed using a different user's OAuth account. In my test, this
allowed the victim account's username to be changed through Flask-
Security-Too's built-in /change-username route.

A likely fix is to reject OAuth verification unless the resolved OAuth
user matches current_user before updating session["fs_paa"].
Record
GHSA-97r5-pg8x-p63p
Weakness
CWE-287
Updated
2026-11-02
NVD 5.3

Flask-Security-Too allows users to add security features to their Flask applicationa. Version 5.8.0's OAuth reauthentication flow can mark a session as fresh after verifying an OAuth account that belongs to a different user. If an attacker can operate an already-authenticated but stale victim session, they can complete OAuth verification using their own OAuth identity. The victim session is then treated as recently reauthenticated, allowing freshness-protected account actions to proceed. Version 5.8.1 contains a fix for this issue.

Record
CVE-2026-46715
CVSS 4.0
5.3 MediumCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Weakness
CWE-287
Updated
2026-11-02
OSV 5.3

Flask-Security-Too OAuth reauthentication freshness bypass via cross- user OAuth identity acceptance

Flask-Security-Too allows users to add security features to their Flask applicationa. Version 5.8.0's OAuth reauthentication flow can mark a session as fresh after verifying an OAuth account that belongs to a different user. If an attacker can operate an already-authenticated but stale victim session, they can complete OAuth verification using their own OAuth identity. The victim session is then treated as recently reauthenticated, allowing freshness-protected account actions to proceed. Version 5.8.1 contains a fix for this issue.

Record
CVE-2026-46715
CVSS 4.0
5.3 MediumCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N
Weakness
CWE-287
Updated
2026-11-02
OSVGHSA-97r5-pg8x-p63p No score

Flask-Security-Too OAuth reauthentication freshness bypass via cross- user OAuth identity acceptance

Summary

Flask-Security-Too 5.8.0's OAuth reauthentication flow can mark a session as fresh after verifying an OAuth account that belongs to a different user.

If an attacker can operate an already-authenticated but stale victim session, they can complete OAuth verification using their own OAuth identity. The victim session is then treated as recently reauthenticated, allowing freshness-protected account actions to proceed. This was reproduced against the built-in /change-username route.

Details

The issue is in the OAuth verification callback.

_oauth_response_common() resolves the OAuth provider identity to a Flask-Security user:

  • flask_security/oauth_glue.py:101-108

oauth_verify_response() then accepts any resolved user and updates the current session freshness timestamp:

  • flask_security/oauth_glue.py:182-214
  • flask_security/oauth_glue.py:201-204

The missing check is that the OAuth-resolved user must match the current authenticated session user. In the failing case:

So the attacker is not logging in as the victim, but they are satisfying the victim session's reauthentication requirement with a different account.

PoC

Tested version:

  • Flask-Security-Too 5.8.0
  • tag 5.8.0
  • commit 08288dff6907e413d848a16aaf43fc2c2b2a3b72

Used a minimal Flask app with:

SECURITY_OAUTH_ENABLE = True
SECURITY_OAUTH_BUILTIN_PROVIDERS = ["github"]
SECURITY_FRESHNESS = timedelta(seconds=1)
SECURITY_FRESHNESS_GRACE_PERIOD = timedelta(seconds=0)
SECURITY_USERNAME_ENABLE = True
SECURITY_CHANGE_USERNAME = True

The OAuth provider was replaced with a localhost mock provider
returning [email protected]. This avoids hitting a live third-party
provider while still exercising Flask-Security-Too's real OAuth
verification handler.

Reproduction steps:

1. Log in as [email protected].
2. Wait until the session is no longer fresh.
3. Confirm POST /change-username is blocked with 401 and
   reauth_required=true.
4. Start OAuth verification with POST /login/oauth-verify-start/
   github.
5. Complete the callback with an OAuth identity for
   [email protected].
6. Confirm the session is still for [email protected], but fs_paa has
   been updated.
7. Retry POST /change-username.
8. The victim user's username is changed successfully.

Observed result:

{
  "pre_bypass_status": 401,
  "pre_bypass_reauth_required": true,
  "attacker_identity": "[email protected]",
  "oauth_verify_response_status": 302,
  "post_bypass_change_username_status": 200,
  "final_email": "[email protected]",
  "final_username": "victimowned1777878574",
  "direct_impact_verified": true
}

Note: CSRF was disabled in the local harness only to keep the test
focused on the reauthentication check. This is not a CSRF bypass
report.

This bypasses Flask-Security-Too's freshness/reauthentication
boundary.

Applications using OAuth verification together with freshness-
protected account operations may allow a stale victim session to be
refreshed using a different user's OAuth account. In my test, this
allowed the victim account's username to be changed through Flask-
Security-Too's built-in /change-username route.

A likely fix is to reject OAuth verification unless the resolved OAuth
user matches current_user before updating session["fs_paa"].
Record
GHSA-97r5-pg8x-p63p
Weakness
CWE-287
Updated
2026-11-02
OSVPYSEC-2026-2478 No score

Flask-Security-Too OAuth reauthentication freshness bypass via cross- user OAuth identity acceptance

Summary

Flask-Security-Too 5.8.0's OAuth reauthentication flow can mark a session as fresh after verifying an OAuth account that belongs to a different user.

If an attacker can operate an already-authenticated but stale victim session, they can complete OAuth verification using their own OAuth identity. The victim session is then treated as recently reauthenticated, allowing freshness-protected account actions to proceed. This was reproduced against the built-in /change-username route.

Details

The issue is in the OAuth verification callback.

_oauth_response_common() resolves the OAuth provider identity to a Flask-Security user:

  • flask_security/oauth_glue.py:101-108

oauth_verify_response() then accepts any resolved user and updates the current session freshness timestamp:

  • flask_security/oauth_glue.py:182-214
  • flask_security/oauth_glue.py:201-204

The missing check is that the OAuth-resolved user must match the current authenticated session user. In the failing case:

So the attacker is not logging in as the victim, but they are satisfying the victim session's reauthentication requirement with a different account.

PoC

Tested version:

  • Flask-Security-Too 5.8.0
  • tag 5.8.0
  • commit 08288dff6907e413d848a16aaf43fc2c2b2a3b72

Used a minimal Flask app with:

SECURITY_OAUTH_ENABLE = True
SECURITY_OAUTH_BUILTIN_PROVIDERS = ["github"]
SECURITY_FRESHNESS = timedelta(seconds=1)
SECURITY_FRESHNESS_GRACE_PERIOD = timedelta(seconds=0)
SECURITY_USERNAME_ENABLE = True
SECURITY_CHANGE_USERNAME = True

The OAuth provider was replaced with a localhost mock provider
returning [email protected]. This avoids hitting a live third-party
provider while still exercising Flask-Security-Too's real OAuth
verification handler.

Reproduction steps:

1. Log in as [email protected].
2. Wait until the session is no longer fresh.
3. Confirm POST /change-username is blocked with 401 and
   reauth_required=true.
4. Start OAuth verification with POST /login/oauth-verify-start/
   github.
5. Complete the callback with an OAuth identity for
   [email protected].
6. Confirm the session is still for [email protected], but fs_paa has
   been updated.
7. Retry POST /change-username.
8. The victim user's username is changed successfully.

Observed result:

{
  "pre_bypass_status": 401,
  "pre_bypass_reauth_required": true,
  "attacker_identity": "[email protected]",
  "oauth_verify_response_status": 302,
  "post_bypass_change_username_status": 200,
  "final_email": "[email protected]",
  "final_username": "victimowned1777878574",
  "direct_impact_verified": true
}

Note: CSRF was disabled in the local harness only to keep the test
focused on the reauthentication check. This is not a CSRF bypass
report.

This bypasses Flask-Security-Too's freshness/reauthentication
boundary.

Applications using OAuth verification together with freshness-
protected account operations may allow a stale victim session to be
refreshed using a different user's OAuth account. In my test, this
allowed the victim account's username to be changed through Flask-
Security-Too's built-in /change-username route.

A likely fix is to reject OAuth verification unless the resolved OAuth
user matches current_user before updating session["fs_paa"].
Record
PYSEC-2026-2478
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
flask-security-too
PyPI
5.8.0 up to 5.8.1
5.8.1

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-46715 is a medium vulnerability (CVSS 5.3) in Flask-middleware Flask-security-too, published May 22, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.35%, the 28th percentile. Fixed in flask-security-too 5.8.1.

References

MoveEnter Open