Skip to main content
Vulnerability Database/CVE-2025-30149

CVE-2025-30149: OpenEMR Reflected XSS Vulnerability

CVE-2025-30149 is a reflected XSS flaw in OpenEMR that allows attackers to inject malicious scripts through the target parameter. This post explains its technical details, affected versions, security impact, and mitigation steps.

Published:

CVE-2025-30149 Overview

CVE-2025-30149 is a reflected cross-site scripting (XSS) vulnerability in OpenEMR, a free and open source electronic health records and medical practice management application. The flaw resides in the AJAX Script interface at interface/super/layout_listitems_ajax.php and is triggered through the unsanitized target parameter. An authenticated attacker can craft a malicious URL that, when visited by a logged-in user, executes attacker-controlled JavaScript in the victim's browser session. The vulnerability is tracked as [CWE-79] and has been fixed in OpenEMR version 7.0.3.

Critical Impact

Reflected XSS in a healthcare application allows attackers to hijack authenticated sessions, exfiltrate protected health information (PHI), or perform actions on behalf of clinical users.

Affected Products

  • OpenEMR versions prior to 7.0.3
  • interface/super/layout_listitems_ajax.php AJAX endpoint
  • Deployments exposing the administrative layout interface to authenticated users

Discovery Timeline

  • 2025-03-31 - CVE-2025-30149 published to NVD
  • 2026-06-17 - Last updated in NVD database

Technical Details for CVE-2025-30149

Vulnerability Analysis

The vulnerable script layout_listitems_ajax.php generates JavaScript output that references a form element identified by the user-supplied target request parameter. The parameter value is embedded in dynamically produced JavaScript returned to the browser. Because the response is served with a permissive content type and the parameter is reflected into executable script context, an attacker can inject arbitrary JavaScript by crafting a specially formed target value.

Successful exploitation requires an authenticated OpenEMR session and user interaction, typically clicking a crafted link. Impact includes session token theft, forced actions in the OpenEMR interface, and disclosure of patient data visible to the targeted user.

Root Cause

The root cause is improper neutralization of input during web page generation. The target parameter flows into a JavaScript response without content-type hardening, enabling script injection when the response is interpreted as HTML by the browser.

Attack Vector

The attack vector is network-based and requires low privileges plus user interaction. An attacker sends a victim a URL pointing to the vulnerable endpoint with a malicious target value. When the authenticated victim loads the URL, the injected payload executes in the OpenEMR origin.

php
 $res = sqlStatement("SELECT option_id FROM list_options WHERE list_id = ? AND activity = 1 " .
   "ORDER BY seq, option_id", array($listid));
 
+// Set content type to mitigate xss
+header('Content-Type: text/javascript');
 echo "var itemsel = document.forms[0][" . js_escape($target) . "];\n";
 echo "var j = 0;\n";
 echo "itemsel.options[j++] = new Option(" . js_escape("-- " . xl('Please Select') . " --") . ",'',false,false);\n";

Source: OpenEMR security fix commit 6cb7059. The patch adds an explicit Content-Type: text/javascript header so browsers interpret the response as JavaScript rather than HTML, preventing injected markup from executing.

Detection Methods for CVE-2025-30149

Indicators of Compromise

  • Web server access logs containing requests to interface/super/layout_listitems_ajax.php with target parameter values that include characters such as <, >, ", or encoded script tags.
  • Referer headers pointing to external domains delivering crafted links to OpenEMR users.
  • Unexpected outbound requests from browser sessions immediately after visiting OpenEMR AJAX endpoints.

Detection Strategies

  • Deploy a web application firewall rule that inspects the target query parameter for script-injection patterns on the vulnerable path.
  • Enable server-side request logging with full query string capture to allow retrospective hunting for crafted payloads.
  • Alert on OpenEMR responses from layout_listitems_ajax.php that lack the Content-Type: text/javascript header, indicating unpatched instances.

Monitoring Recommendations

  • Monitor authenticated OpenEMR sessions for anomalous DOM activity or token exfiltration using browser isolation telemetry where available.
  • Correlate email and messaging gateway logs for inbound links referencing OpenEMR hostnames and the vulnerable path.
  • Track administrative action logs within OpenEMR for actions initiated shortly after a user clicked an external link.

How to Mitigate CVE-2025-30149

Immediate Actions Required

  • Upgrade all OpenEMR instances to version 7.0.3 or later, which contains the fix in commit 6cb7059.
  • Review web server logs for prior exploitation attempts against layout_listitems_ajax.php and rotate session cookies for impacted users.
  • Restrict administrative interfaces to trusted networks and enforce multi-factor authentication for OpenEMR accounts.

Patch Information

The fix is published in the GitHub Security Advisory GHSA-fwfv-8583-6rr7 and implemented in the OpenEMR security commit. The patch forces the AJAX response to be served as text/javascript, preventing the browser from rendering injected HTML. Upgrading to OpenEMR 7.0.3 applies this change.

Workarounds

  • Add a web server or reverse proxy rule that strips or sanitizes the target query parameter on requests to interface/super/layout_listitems_ajax.php until upgrading.
  • Enforce a strict Content Security Policy that disallows inline script execution from unexpected sources on the OpenEMR origin.
  • Require users to authenticate through a session-scoped portal and educate clinical staff to avoid clicking unsolicited OpenEMR URLs.
bash
# Example WAF rule (ModSecurity) blocking script injection in the target parameter
SecRule REQUEST_URI "@contains /interface/super/layout_listitems_ajax.php" \
  "chain,phase:2,deny,status:403,id:1030149,msg:'CVE-2025-30149 OpenEMR XSS attempt'"
  SecRule ARGS:target "@rx (?i)(<script|onerror=|javascript:|%3Cscript)" "t:none,t:urlDecode"

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.