CVE-2026-33912 Overview
OpenEMR is a free and open source electronic health records and medical practice management application. Prior to version 8.0.0.3, an authenticated attacker could craft a malicious form that, when submitted by a victim, executes arbitrary JavaScript in the victim's browser session. This Cross-Site Scripting (XSS) vulnerability arises from improper input validation in the custom/ajax_download.php file, allowing user-controlled POST and GET parameters to be processed without adequate sanitization.
Critical Impact
An authenticated attacker can execute arbitrary JavaScript in victims' browser sessions, potentially leading to session hijacking, data theft, or unauthorized actions within the OpenEMR healthcare application managing sensitive patient records.
Affected Products
- OpenEMR versions prior to 8.0.0.3
- open-emr openemr
Discovery Timeline
- 2026-03-25 - CVE CVE-2026-33912 published to NVD
- 2026-03-26 - Last updated in NVD database
Technical Details for CVE-2026-33912
Vulnerability Analysis
This vulnerability is classified as CWE-79 (Improper Neutralization of Input During Web Page Generation), commonly known as Cross-Site Scripting (XSS). The flaw exists in OpenEMR's custom/ajax_download.php file, where user-supplied input from POST and GET parameters was processed without proper sanitization or validation. When a victim user submits a form crafted by an authenticated attacker, malicious JavaScript code embedded in the form data can execute within the victim's browser context.
The attack requires low privileges (authenticated user) and user interaction (victim must submit the malicious form). However, due to the changed scope characteristic, a successful exploitation could affect resources beyond the vulnerable component, potentially compromising confidentiality and integrity of the healthcare application and patient data.
Root Cause
The root cause is improper input validation of user-controlled parameters in custom/ajax_download.php. The vulnerable code directly used POST parameters ($_POST['reportID'], $_POST['ruleID'], $_POST['counter'], $_POST['provider_id']) and GET parameters ($_GET['fileName']) without proper type casting, filtering, or sanitization, allowing injection of malicious payloads.
Attack Vector
This is a network-based attack requiring an authenticated user to craft a malicious form. The attack vector involves:
- An authenticated attacker creates a specially crafted form containing malicious JavaScript
- The attacker tricks a victim user into submitting this form
- The victim's browser executes the arbitrary JavaScript in the context of their OpenEMR session
- The attacker can then hijack sessions, steal sensitive healthcare data, or perform unauthorized actions
// Vulnerable code (before patch)
$reportID = $_POST['reportID'];
$ruleID = $_POST['ruleID'];
$counter = $_POST['counter'];
$fileName = $_GET['fileName'] ?? "";
$provider_id = $_POST['provider_id'];
// Initial patch - type casting
$reportID = (int) $_POST['reportID']; // sanitize to int: db column is bigint
$ruleID = (string) $_POST['ruleID']; // validated later by its presence in $criteriaPatients
$fileName = $_GET['fileName'] ?? ''; // validated later by check_file_dir_name()
$provider_id = (int) $_POST['provider_id']; // sanitize to int: db column is bigint
Source: GitHub Commit Update
// Final patch - using filter_input for more robust validation
$reportID = filter_input(INPUT_POST, 'reportID', FILTER_VALIDATE_INT);
$ruleID = filter_input(INPUT_POST, 'ruleID') ?? ''; // validated later by its presence in $criteriaPatients
$fileName = filter_input(INPUT_GET, 'fileName') ?? ''; // validated later by check_file_dir_name()
$provider_id = filter_input(INPUT_POST, 'provider_id', FILTER_VALIDATE_INT);
if ($reportID === null || $reportID === false) {
echo xlt("FAILURE: Invalid report ID");
exit(0);
}
Source: GitHub Commit Update
Detection Methods for CVE-2026-33912
Indicators of Compromise
- Unexpected JavaScript execution or browser behavior when interacting with OpenEMR forms
- Suspicious form submissions containing encoded script tags or JavaScript event handlers
- Unusual network requests originating from OpenEMR pages to external domains
- Session anomalies or unauthorized actions performed under legitimate user accounts
Detection Strategies
- Monitor web application logs for suspicious parameters containing script tags, event handlers, or encoded payloads in requests to custom/ajax_download.php
- Implement Web Application Firewall (WAF) rules to detect and block XSS payload patterns in form submissions
- Deploy Content Security Policy (CSP) headers to restrict inline script execution and report violations
- Enable browser-based XSS auditor logging and monitor for triggered events
Monitoring Recommendations
- Review OpenEMR access logs for unusual patterns in ajax_download.php requests
- Set up alerts for form submissions containing potentially malicious characters or encoding patterns
- Monitor for CSP violation reports indicating attempted script injections
- Track user session activity for anomalies that might indicate session hijacking
How to Mitigate CVE-2026-33912
Immediate Actions Required
- Upgrade OpenEMR to version 8.0.0.3 or later immediately
- Review system logs for potential exploitation attempts targeting custom/ajax_download.php
- Implement strict Content Security Policy headers to mitigate XSS impact
- Conduct a security review of user accounts for any unauthorized activity
Patch Information
The vulnerability has been addressed in OpenEMR version 8.0.0.3. The patch implements proper input validation using PHP's filter_input() function with appropriate filters for integer parameters and adds explicit validation checks before processing. Two commits address this issue:
- Commit 24dd47c - Initial fix using type casting
- Commit ae2a9e5 - Enhanced fix using filter_input()
For more details, refer to the GitHub Security Advisory GHSA-cpph-949w-w79v.
Workarounds
- If immediate patching is not possible, consider restricting access to custom/ajax_download.php through web server configuration
- Implement a Web Application Firewall with XSS protection rules
- Enable strict Content Security Policy headers to prevent inline script execution
- Limit authenticated user access to minimize the potential attack surface
# Apache configuration to add CSP headers as temporary mitigation
<IfModule mod_headers.c>
Header set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'"
</IfModule>
# Nginx configuration alternative
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'" always;
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

