OpenEMR's one-time token ignored its own limits
Patient portals often use a service token to move a user from a clinic workflow into an authenticated session. The token is supposed to be narrow, short-lived, and consumed once. OpenEMR's OneTimeAuth implementation had the opposite behavior in affected versions: it ignored its own one-time-use and maximum-access flags, kept consumed service tokens valid, and checked the login PIN without rate limiting or strict comparison.
CVE-2026-124445 affects OpenEMR from 7.0.1 before 8.4.0. The CVE record describes token replay and PIN brute force and rates the issue CVSS v4.0 9.3 and CVSS v3.1 9.8. The impact is a patient-portal session, with access to the protected health information available through that session.
The vulnerable file is src/Common/Auth/OneTimeAuth.php. The advisory says the flags enforce_onetime_use and max_access_count were ignored, consumed service_auth tokens were never revoked, and the PIN check lacked rate limiting or a strict comparison. Those are separate failures that reinforce one another. Even a token with a short intended life can be reused if the service never records consumption. A weak PIN becomes easier to guess when attempts are unlimited.
Why a "one-time" token needs state
One-time semantics are not a property of the token string. They are a property of the server's record of use. The server must atomically mark a token consumed before issuing a session, reject a second redemption, and retain enough state to enforce a maximum access count. If two requests arrive together, a read-then-write check can still allow both unless the transition is atomic.
The PIN adds a second factor only if it is compared safely and attempts are bounded. A non-strict comparison can produce unexpected matches when values have different types or representations. A missing rate limit removes the cost of guessing. If the token is long-lived or reusable, an attacker can work offline or online against the PIN until a session is created.
Captured tokens can come from browser history, referrer leakage, logs, email links, shared workstations, or a compromised endpoint. The article does not need to claim one delivery method. The design must assume that a token can leak and that the server will enforce its scope.
Which deployments need action
Any OpenEMR deployment from 7.0.1 through 8.3.x should be treated as affected for this issue. Upgrade to 8.4.0 or later. If the portal is not internet-facing, the risk is lower but not absent. Internal users, compromised endpoints, and shared links can still reach the service.
Inventory patient-portal integrations that create service tokens. Identify where tokens are stored, how long they remain valid, and whether they can open sessions without an interactive login. Review reverse-proxy logs for repeated token redemption attempts, failed PINs, and sessions created from unexpected networks.
The patch does not retroactively invalidate every token an attacker may have collected. After upgrading, rotate or revoke service tokens that could have been exposed and review active portal sessions. Check whether a compromised clinic account could issue new tokens or change the portal authentication flow.
Detection and verification
Look for the same token used more than once, successful sessions after repeated PIN failures, and requests that bypass the normal login sequence. Correlate the token identifier with the patient or user account, source address, user agent, and session start time. Avoid putting the full token or PHI into monitoring systems.
After the upgrade, test with a controlled token that has a maximum-use count greater than one. Confirm that the count is enforced, that a consumed token is rejected, and that a burst of incorrect PIN attempts is throttled. Test concurrent redemptions, because that is where many one-time controls fail.
Put rate limiting at the application and the edge. Use a cryptographically random PIN comparison with constant-time semantics where applicable, and store only the data needed to verify it. Log the decision and the reason code without recording the secret.
The broader lesson is that identity shortcuts need the same lifecycle controls as passwords. A token labeled one-time is not a security control until the server can prove that the second use fails. OpenEMR's advisory is a reminder to test the state transition beyond the presence of a flag in the configuration.
Top comments (0)