Summary
CVE-2026-39923 is a critical authentication bypass in the Flarum forum framework. The SavePasswordController::handle() method fails to validate the expiration of password reset tokens, allowing an unauthenticated attacker to reuse an expired reset token by submitting it directly to the reset processing endpoint and take over any user account. The flaw affects all versions of Flarum before 1.8.16 and is rated critical.
Technical details
- Root cause: The password reset flow does not enforce token expiry.
SavePasswordController::handle()accepts a reset token without checking whether it has passed its lifetime (CWE-324: Use of a Key Past its Expiration Date). - Trigger conditions: An attacker submits a previously issued but expired password reset token directly to the reset processing endpoint (
POST /reset), bypassing the intended 24-hour token validity window. - Attack vector: Network, unauthenticated. No prior privileges or user interaction with the victim are required.
- Impact: Reset of an arbitrary user’s password, leading to full account takeover, including administrator accounts, with corresponding loss of confidentiality and integrity.
Affected software
- Flarum (flarum/framework) — all versions prior to 1.8.16.
Severity
- CVSS v4.0: 9.2 (Critical) —
CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N - CVSS v3.1: 8.1 (High) —
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Mitigation and recommended actions
- Immediate: Upgrade to Flarum 1.8.16 or later, which enforces an expiry check on password reset token submission (PR #4545).
- If no patch can be applied immediately: Restrict network access to the reset endpoint where feasible, monitor for repeated or anomalous requests to the password reset processing endpoint, and require affected users to request fresh reset tokens after upgrading.
How IONIX identifies potentially affected assets
IONIX matches the following signals against data already collected when it crawled the asset; identifying the technology sends no request beyond that crawl.
- Raw response body:
<div id="flarum-loading" - JavaScript objects present once the page runs:
app.cache.discussionList,app.forum.freshness

