CSIRTS // UNIFIED SECURITY ADVISORY FEEDSYS ● ONLINE · POWERED BY INTELFUSIONS.COM

GHSA-f66q-9rf6-8795: Flask-Security-Too: WebAuthn reauthentication freshness bypass via cross-user assertion

medium
Summary Flask-Security-Too 5.8.0 and 5.8.1 mark a session as reauthentication-fresh after processing a WebAuthn assertion whose proven credential belongs to a different user than the currently authenticated session user. The check that GHSA-97r5-pg8x-p63p added on the OAuth reauthentication path (user.email == current_user.email) is missing on the WebAuthn reauthentication path. An attacker who owns any WebAuthn credential registered to any account on the deployment can satisfy a victim session's freshness gate by submitting their own WebAuthn proof into the victim session. Affected versions Flask-Security-Too >= 5.8.0, <= 5.8.1 (current main commit 5c44c76e33a20b67d02115e26d2da4bab18c094e). GHSA-97r5-pg8x-p63p (published 2026-05-22) shipped its fix in 5.8.1 only on oauth_glue.py; webauthn.py was not touched and remains exploitable in 5.8.1. Privilege required Authenticated attacker on the same Flask-Security deployment, owning at least one WebAuthn credential of any usage (first / secondary / verify) that is registered to their own account. The attacker also needs the ability to drive HTTP requests against the WebAuthn endpoints inside the victim session (e.g. a separate gadget such as CSRF + cookie-based auth, an XSS that doesn't reach the cookie itself but can move the session through endpoints, or an existing session-fixation gadget; or the rarer but easier case of an attacker who has direct access to the victim's not-yet-fresh session via a shared browser). The point of the freshness gate is to defend exactly that "I have the session but it isn't fresh enough to do sensitive things" position, so any context in which freshness would have protected the victim is also the context in which this bypass matters. Vulnerable code flask_security/webauthn.py:846-889 (commit 5c44c76e33a20b67d02115e26d2da4bab18c094e): @auth_required(lambda: cv("API_ENABLED_METHODS")) def webauthn_verify_response(token: str) -> ResponseValue: form = t.cast( WebAuthnSigninResponseFor

Details

Source
GitHub Security Advisories (INTL · database · site)
Severity
medium
Published
2026-07-07
Last updated
2026-07-07
Exploitation
Not in CISA KEV at last sync

Original advisory: https://github.com/advisories/GHSA-f66q-9rf6-8795

More from GitHub Security Advisories