CVE-2026-25220 Overview
CVE-2026-25220 is an authorization bypass vulnerability in OpenEMR, a widely deployed open source electronic health records and medical practice management application. The flaw resides in the Message Center component, where the messages.php endpoint accepts the URL parameter show_all=yes and forwards it to the getPnotesByUser() function. The backend fails to verify administrator privileges before returning the complete set of internal messages across all users. Any authenticated user can issue the request and read messages belonging to other users. Versions prior to 8.0.0 are affected, and version 8.0.0 contains the patch. This issue is categorized under CWE-639 (Authorization Bypass Through User-Controlled Key).
Critical Impact
Any authenticated OpenEMR user can read the entire internal message list, exposing patient-related communications and potentially protected health information (PHI).
Affected Products
- OpenEMR versions prior to 8.0.0
- open-emr/openemr software package
- Deployments exposing the Message Center to authenticated non-admin users
Discovery Timeline
- 2026-02-25 - CVE-2026-25220 published to NVD
- 2026-02-27 - Last updated in NVD database
Technical Details for CVE-2026-25220
Vulnerability Analysis
The vulnerability sits in OpenEMR's internal messaging subsystem, accessible through messages.php. The endpoint reads the show_all query parameter directly from the request. When show_all=yes is supplied, the controller invokes getPnotesByUser() with parameters that broaden the query to return notes belonging to every user in the system. The function does not consult the caller's role or assigned access control list before returning results.
The user interface compounds the exposure. The "Show All" link that triggers the show_all=yes parameter is rendered for non-admin users, signaling the functionality as legitimate. An attacker does not need to discover the parameter through code review or fuzzing because the application itself exposes it. The flaw is a horizontal and vertical privilege escalation combined into a single missing check.
Root Cause
The root cause is missing authorization enforcement on a server-side parameter that controls data scope. The application treats the show_all flag as a presentation toggle rather than an access control boundary. No server-side check confirms that the requesting session belongs to an administrator before the broader query executes. This matches the CWE-639 pattern, where authorization decisions hinge on user-controlled input.
Attack Vector
Exploitation requires only a valid low-privilege OpenEMR account. An authenticated attacker navigates to messages.php?show_all=yes or clicks the visible "Show All" link. The server returns the consolidated message list, including notes addressed to clinicians, administrators, and other staff. Because OpenEMR's internal messages frequently reference patient identifiers, appointments, and clinical context, the disclosed data can constitute protected health information under HIPAA. No additional payload, social engineering, or client-side interaction is required.
No public proof-of-concept exploit code is listed for this issue. See the GitHub Security Advisory and the upstream commit for the authoritative technical description and fix.
Detection Methods for CVE-2026-25220
Indicators of Compromise
- Web server access logs containing requests to messages.php with the query string show_all=yes originating from non-administrator session identifiers.
- Unusually large response sizes from messages.php returned to standard clinical or front-desk user accounts.
- Repeated access to the Message Center from accounts that historically have no business need to view internal messages.
Detection Strategies
- Correlate authenticated session role with the presence of show_all=yes in request URIs; flag any mismatch where the session is not an administrator.
- Review OpenEMR audit logs and PHP application logs for invocations of getPnotesByUser() returning record counts that exceed a per-user baseline.
- Hunt across web proxy and WAF telemetry for the exact pattern GET /interface/main/messages/messages.php?show_all=yes and pivot on the associated user identifier.
Monitoring Recommendations
- Enable verbose access logging on the OpenEMR web tier and forward logs to a centralized analytics platform for retention and query.
- Establish alerting on access control anomalies in healthcare applications, focusing on endpoints that aggregate data across users.
- Periodically audit which OpenEMR accounts have viewed messages outside their assigned scope and validate against role assignments.
How to Mitigate CVE-2026-25220
Immediate Actions Required
- Upgrade OpenEMR to version 8.0.0 or later, which contains the authorization check that blocks non-administrators from using show_all=yes.
- Review web server and application logs for prior requests to messages.php?show_all=yes from non-admin users to scope potential exposure.
- Rotate or review credentials of accounts that may have abused the endpoint, and notify your privacy or compliance officer if PHI was exposed.
Patch Information
The fix is delivered in OpenEMR 8.0.0. The upstream patch is published as commit 9f2c44fc88fc051fcf0b6922c373977543e6b2af. Administrators should follow the standard OpenEMR upgrade procedure, including database migrations and post-upgrade verification. Refer to the GitHub Security Advisory GHSA-phcp-7qjx-83cm for the vendor's authoritative guidance.
Workarounds
- Restrict access to messages.php?show_all=yes at the reverse proxy or web application firewall by blocking requests that include the show_all parameter for sessions associated with non-administrator roles.
- Apply the upstream patch from commit 9f2c44fc88fc051fcf0b6922c373977543e6b2af to running 7.x deployments where an immediate version upgrade is not feasible.
- Limit Message Center access to a smaller set of trusted users through network segmentation or reverse-proxy authorization rules until the upgrade is completed.
# Example NGINX rule to block the vulnerable parameter for unauthenticated
# or non-admin sessions until OpenEMR is upgraded to 8.0.0
location ~* /interface/main/messages/messages\.php$ {
if ($arg_show_all = "yes") {
return 403;
}
proxy_pass http://openemr_backend;
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

