CVE-2026-33914 Overview
OpenEMR is a free and open source electronic health records and medical practice management application. Prior to version 8.0.0.3, the PostCalendar module contains a blind SQL injection vulnerability in the categoriesUpdate administrative function. The dels POST parameter is read via pnVarCleanFromInput(), which only strips HTML tags and performs no SQL escaping. The value is then interpolated directly into a raw SQL DELETE statement that is executed unsanitized via Doctrine DBAL's executeStatement().
Critical Impact
An authenticated attacker with administrative privileges can exploit this blind SQL injection vulnerability to extract, modify, or delete sensitive patient health records and system data from the OpenEMR database.
Affected Products
- OpenEMR versions prior to 8.0.0.3
- PostCalendar module with vulnerable categoriesUpdate function
- OpenEMR installations using Doctrine DBAL for database operations
Discovery Timeline
- 2026-03-26 - CVE CVE-2026-33914 published to NVD
- 2026-03-26 - Last updated in NVD database
Technical Details for CVE-2026-33914
Vulnerability Analysis
This vulnerability is a classic SQL Injection (CWE-89) occurring in the PostCalendar administrative module of OpenEMR. The vulnerable code path exists in the categoriesUpdate function where user-controlled input from the dels POST parameter is processed through pnVarCleanFromInput(). This sanitization function is inadequate as it only removes HTML tags but does not perform proper SQL escaping or parameterized query binding.
The unsanitized input is directly concatenated into a raw SQL DELETE statement, creating a blind SQL injection condition. Because the query is executed via Doctrine DBAL's executeStatement() without prepared statements or parameter binding, an attacker can inject arbitrary SQL commands that will be executed against the backend database.
Root Cause
The root cause is insufficient input validation and the absence of parameterized queries. The pnVarCleanFromInput() function was designed to sanitize HTML content but was incorrectly relied upon for SQL context sanitization. This architectural oversight allows SQL metacharacters to pass through unfiltered and be interpreted as SQL syntax rather than data.
Attack Vector
The attack vector is network-based, requiring an authenticated attacker with administrative access to the OpenEMR system. The attacker submits a specially crafted POST request to the categoriesUpdate function with malicious SQL code embedded in the dels parameter. Because this is a blind SQL injection, the attacker cannot directly see query results but can infer information through time-based or boolean-based techniques, or use stacked queries to modify data.
// Vulnerable code (before patch)
$delete = "DELETE FROM $pntable[postcalendar_categories] WHERE pc_catid IN ($dels)";
// $dels is directly interpolated without SQL escaping
// Patched code (version 8.0.0.3)
$safeDels = implode(',', array_map(intval(...), explode(',', $dels)));
$delete = "DELETE FROM $pntable[postcalendar_categories] WHERE pc_catid IN ($safeDels)";
// Input is now sanitized by casting each value to integer
Source: GitHub Commit 1b851fc9af84f181ad7a84210a168d0d568cd442
Detection Methods for CVE-2026-33914
Indicators of Compromise
- Unusual or malformed POST requests to the PostCalendar categoriesUpdate administrative endpoint
- Database query logs showing anomalous DELETE statements with SQL injection patterns such as UNION, SLEEP(), or BENCHMARK() functions
- Unexpected modifications or deletions in the postcalendar_categories table
- Web server access logs with suspicious dels parameter values containing SQL syntax characters
Detection Strategies
- Implement Web Application Firewall (WAF) rules to detect SQL injection patterns in POST parameters targeting OpenEMR administrative functions
- Enable database query logging and monitor for unusual DELETE operations or time-based SQL functions
- Deploy intrusion detection systems (IDS) with signatures for SQL injection attacks targeting healthcare applications
- Audit administrative user activity and flag unusual bulk operations against calendar category data
Monitoring Recommendations
- Monitor authentication logs for administrative account access patterns that deviate from normal behavior
- Set up alerts for database errors or timeout conditions that may indicate time-based blind SQL injection attempts
- Implement rate limiting on administrative API endpoints to slow down automated exploitation attempts
- Review OpenEMR audit logs for changes to calendar categories that were not initiated through normal workflows
How to Mitigate CVE-2026-33914
Immediate Actions Required
- Upgrade OpenEMR to version 8.0.0.3 or later immediately
- Review database audit logs for evidence of exploitation attempts
- Restrict administrative access to the PostCalendar module to only essential personnel
- Implement network-level access controls to limit exposure of the OpenEMR administrative interface
Patch Information
OpenEMR has released version 8.0.0.3 which addresses this vulnerability. The patch implements proper input sanitization by casting each comma-separated value in the dels parameter to an integer using array_map(intval(...), explode(',', $dels)). This ensures that only numeric values can be included in the SQL query, effectively neutralizing any SQL injection payload.
For detailed patch information, refer to the GitHub Security Advisory GHSA-rq3v-38x5-3rm5 and the official release v8.0.0.3.
Workarounds
- If immediate patching is not possible, disable or restrict access to the PostCalendar module's administrative functions until the update can be applied
- Implement application-layer filtering to validate that the dels parameter contains only numeric, comma-separated values
- Deploy a WAF rule to block requests containing SQL injection patterns in the dels parameter
- Consider placing the OpenEMR administrative interface behind a VPN or additional authentication layer to reduce attack surface
# Example: Apache mod_security rule to block suspicious dels parameter
SecRule ARGS:dels "@rx (\%27)|(\')|(\-\-)|(\%23)|(#)" \
"id:100001,phase:2,deny,status:403,msg:'SQL Injection attempt in dels parameter'"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

