Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessObtain valid recovery token for target
-
DeliveryFire concurrent POSTs to /user/confirm_account/<token>
-
ExploitBoth requests pass nonce check before commit
-
ExecutionLast commit sets attacker password
-
ImpactLegitimate user locked out, account takeover
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A06:2025 - Insecure Design
ASVS 5.0
V15 - Secure Coding and Architecture Concurrency control, locking
MITRE ATT&CK
1 technique across 1 tactic: Privilege Escalation The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | Exploitation requires the attacker to already hold a VALID, unconsumed single-use recovery token for the target account (issued via the account confirmation/password-reset flow); without a live token the endpoint cannot be driven. The attacker must then send two or more simultaneous requests to /user/confirm_account/<token> and win the narrow check-then-consume race window before the first transaction commits (hence AC:H). No login/authentication to the application is required (PR:N) and no user interaction from the victim is needed at exploit time. Limiting factors: the token prerequisite, the timing precision needed to win the race, and the fact that only pre-fix (unpatched) instances applying separate verify-then-clear operations are vulnerable - the fix collapses these into one conditional UPDATE. The secondary weak-password defect requires the same valid token and simply skips the form's minimum-length/complexity validation. |
| Impact | This is a genuine but moderate-severity flaw whose real-world priority is bounded by a hard prerequisite and by product footprint rather than by the 6.3 CVSS score alone. The vendor's CVSS 4.0 vector (AV:N/AC:H/AT:N/PR:N/UI:N/VC:L/VI:N/VA:N/SC:L) correctly marks network vector, high attack complexity (winning a TOCTOU race requires precise concurrent timing) and no privileges, but the description makes clear the attacker must ALREADY possess a valid single-use recovery token - a condition CVSS captures only indirectly through AC:H, not through PR. EPSS is not provided, the CVE is not in CISA KEV, and no standalone weaponized exploit is published - only a regression test committed alongside the fix demonstrates the race. So there are no signals of active or automatable exploitation. I disagree with the vendor's VI:N: the outcome is overwriting a legitimate user's password (account integrity), which is an integrity impact, so I assess VI:L / I:L. The secondary defect (validation bypass allowing 3-character/empty passwords) further weakens account security but is low impact on its own. Net: a real, patch-worthy authentication-workflow bug, but low urgency given the token prerequisite, AC:H, absence of exploitation signals, and the niche deployment base. |
| Exploit ScenarioDerived | An attacker who has obtained a valid, unexpired recovery token for a target account (e.g., an initial-confirmation link or a leaked reset link) fires two or more concurrent POST requests to /user/confirm_account/<token>, racing the check-then-consume window so more than one request passes nonce verification before any transaction commits. The last commit wins, letting the attacker set a password of their choosing - optionally an empty or 3-character one via the validation-bypass defect - on the account. No standalone public exploit exists, but the vendor's own regression test (test_account_token_race.py) reproduces the race using a thread barrier and two simultaneous clients. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Sep 27, 2026
Time-of-check-to-time-of-use race condition in the account recovery endpoint of vulnerability-lookup (/user/confirm_account/<token>) allows two concurrent HTTP requests carrying the same valid single-use recovery token to both pass the nonce verification step before either transaction commits, so both callers set a password on the target account and the last commit wins. The same view also accepted empty or trivially short (three-character) passwords because it compared the two password fields manually instead of invoking the form's validation logic, bypassing the intended minimum-length and complexity constraints. No public exploit code has been identified at time of analysis, and although the requests are unauthenticated over the network (CVSS:4.0 PR:N), exploitation is gated by the hard prerequisite that the attacker already possesses a live, unconsumed recovery token for the target account plus the timing precision needed to win the race window - a combination the independent assessment captures in its CVSS:3.1 vector AV:N/AC:H/PR:N/UI:N/C:L/I:L/A:N, keeping real-world risk moderate rather than critical.
RemediationAI
Patch available per vendor advisory, delivered through upstream commits 5462bab62d76df852619e01eb67da36c023c8c40 and ad6f22882975516adf193a1a920aaa54025c71d4 (upstream fix available via PR/commit; released patched version not independently confirmed from the supplied data, so verify that the release you deploy contains those commits rather than assuming a tag). The fix introduces User.reset_password_with_account_token, which consumes the nonce digest and writes the password hash in one conditional UPDATE and returns success only when exactly one row changed, and it causes the confirm_account view to roll back and flash 'Impossible to activate this account.' for losing transactions; ensure both the model and view changes are present, since applying only part of the change can leave the weak-password bypass in place. If immediate upgrade is impossible, compensating controls and their trade-offs are: invalidate all outstanding recovery tokens and shorten token TTL so a stolen or leaked link has almost no useful lifetime (users must request fresh links, increasing support load); serialize the redemption path with a row-level lock (SELECT ... FOR UPDATE) or a dedicated one-row consumption record around the digest check-and-clear so only one transaction can proceed (adds lock contention and a small latency cost under load, and must be implemented correctly or it merely narrows the window); front the endpoint with per-token single-flight or short-interval rate limiting at the reverse proxy to make concurrent submissions unlikely (does not eliminate the race for a determined attacker and can be abused to throttle legitimate resets); restrict access to /user/confirm_account/<token> to trusted networks or require an additional out-of-band confirmation step (reduces exposure but degrades usability for remote users); and enforce the password policy server-side independently of the WTForms layer, rejecting empty, short, or trivial passwords before any hash is generated, which directly closes the secondary validation-bypass defect. Monitor and correlate near-simultaneous POST requests to the same recovery token as a detection signal, since the patched code will emit the 'Impossible to activate this account.' outcome for the losing request while unpatched code silently accepts both.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
vulnerability-lookup is an open-source vulnerability intelligence platform maintained by CIRCL and built on a Flask/Werkzeug web stack with SQLAlchemy persistence and WTForms input handling. Account recovery issues a signed confirmation token that embeds a random nonce; the server stores only a SHA-256 digest of that nonce on the User model (account_token_digest in website/models/user.py) and, on redemption, verifies the presented nonce against the digest and then clears it in a separate database operation. That split verify/consume sequence is the classic TOCTOU pattern (CWE-362): two overlapping transactions can both satisfy the nonce check before either commit clears the digest, so both requests proceed to write pwdhash and is_confirmed on the same user row. The view layer (website/web/views/user.py, confirm_account) compounded the design flaw by writing generate_password_hash(form.password1.data) directly after only a manual password1/password2 equality comparison, never calling the WTForms validation, so empty or three-character passwords were accepted despite the configured policy. The upstream fix replaces the read-then-clear sequence with a single conditional UPDATE (WHERE id = self.id AND account_token_digest = candidate) that returns rowcount == 1 only for the winning transaction, making password change and token consumption one database-level compare-and-set, and it routes password persistence through the validated path. The CPE entry cpe:2.3:a:vulnerability-lookup:vulnerability-lookup:*:*:*:*:*:*:*:* indicates no version constraint is recorded, i.e. the whole project line prior to the fix commits is in scope, and any self-hosted or downstream deployment of unpatched code retains the race.
Know when Vulnerability Lookup gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:L/VI:N/VA:N/SC:L/SI:N/SA:N
Network-reachable endpoint with no auth (PR:N) but success needs a valid token plus winning a race (AC:H); overwriting a user's password is an integrity impact (I:L) with limited confidentiality exposure (C:L) and no availability loss.
Primary rating from Vendor (CIRCL).
CVSS VectorVendor: CIRCL
DescriptionCVE.org
The account recovery (password reset) functionality in the vulnerability-lookup web application contains a time-of-check-to-time-of-use (TOCTOU) race condition in the consumption of single-use recovery tokens. The original implementation verified the token nonce against the stored digest and then consumed (cleared) it in separate database operations. Two concurrent HTTP requests presenting the same valid recovery token could both pass the verification check before either transaction committed, allowing both to set their own password on the target account. The last transaction to commit overwrites the first, enabling an attacker who possesses a valid recovery token to replace the legitimate user's password with one of their choosing.
A secondary defect in the same endpoint (confirm_account) allowed a valid recovery link to be used to set an empty or trivially short password (e.g., three characters). The view handler performed only a manual equality comparison between the two password fields and never invoked the form's validation logic, bypassing the intended minimum-length and complexity constraints.
The affected component is the user account recovery endpoint (/user/confirm_account/<token>) and the associated token verification and consumption logic in the User model (website/models/user.py) and the view layer (website/web/views/user.py).
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Authentication bypass attacks exploit flaws in the verification mechanisms that control access to systems and applications.
Race conditions occur when multiple concurrent requests exploit the brief time gap between checking a condition and acting upon it (TOCTOU - Time of Check, Time of Use).
More in Vulnerability Lookup
View allToken replay in Vulnerability-Lookup's account activation and password-recovery mechanism allows an attacker who capture
SSRF guard bypass in Vulnerability Lookup's webhook notification subsystem allows a network attacker to register a webho
Stored cross-site scripting in Vulnerability-Lookup's render_tag_badges Jinja filter allows an authenticated user holdin
Inconsistent authorization enforcement in Vulnerability-Lookup's SSE streaming interface allows self-registered but unco
Server-side request forgery in Vulnerability-Lookup's remote-instance synchronization feature enables an authenticated a
EUVD-2026-87956
GHSA-j3gx-2q66-wg27
NVD
CVE.org
EPSS
Vulnrichment
Exploit-DB