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

CVE-2025-31121: OpenEMR Patient Image EXIF XSS Vulnerability

CVE-2025-31121 is a cross-site scripting flaw in OpenEMR that exploits EXIF metadata in patient images to execute malicious scripts. This post covers the technical details, affected versions, security impact, and mitigation steps.

Published:

CVE-2025-31121 Overview

CVE-2025-31121 is a stored cross-site scripting (XSS) vulnerability in OpenEMR, an open source electronic health records and medical practice management application. The flaw resides in the Patient Image feature, which fails to sanitize EXIF metadata extracted from uploaded images. An attacker with authenticated access can embed malicious script payloads inside the EXIF title field of an image. When a clinician or administrator views the patient record, the browser executes the attacker-controlled JavaScript in the context of the OpenEMR session. The vulnerability affects all OpenEMR versions prior to 7.0.3.1 and is tracked under CWE-79.

Critical Impact

Successful exploitation allows session hijacking, theft of protected health information (PHI), and unauthorized actions performed as the victim user within the OpenEMR application.

Affected Products

  • OpenEMR versions prior to 7.0.3.1
  • Patient Image feature (EXIF metadata parser)
  • Deployments where image uploads are permitted by any authenticated user

Discovery Timeline

  • 2025-04-01 - CVE-2025-31121 published to the National Vulnerability Database
  • 2026-06-17 - Last updated in NVD database

Technical Details for CVE-2025-31121

Vulnerability Analysis

OpenEMR's Patient Image module reads EXIF metadata from uploaded image files and renders selected fields in the patient record view. The application writes the EXIF title value into the HTML response without applying output encoding or input sanitization. This produces a stored XSS condition, because the payload persists in the backing storage and executes every time the record is viewed.

The vulnerability is reachable over the network and requires an authenticated user with privileges to upload patient images. Impact is high for both confidentiality and integrity: an attacker can exfiltrate session cookies, read PHI rendered in the DOM, and submit requests on behalf of the victim through the authenticated session.

EPSS data places this issue in the 97th percentile for exploitation likelihood, which reflects the low technical barrier for weaponizing EXIF-based XSS payloads in healthcare environments.

Root Cause

The root cause is missing output encoding when rendering user-controlled EXIF metadata into HTML context. OpenEMR trusts image metadata as benign descriptive text rather than treating it as untrusted input. The absence of a Content Security Policy enforcing script-source restrictions compounds the issue by allowing inline execution of injected <script> tags or event handlers.

Attack Vector

An attacker with upload privileges crafts an image file whose EXIF title tag contains an HTML or JavaScript payload. Standard tools such as exiftool can inject arbitrary strings into the title field. The attacker uploads the file through the Patient Image feature. When any user, including administrators, opens the affected patient record, the browser parses and executes the payload under the OpenEMR origin.

See the GitHub Security Advisory GHSA-2w94-qmj6-3qxx for additional technical context.

Detection Methods for CVE-2025-31121

Indicators of Compromise

  • Image files uploaded to OpenEMR whose EXIF title, description, or comment fields contain HTML tags, <script> blocks, or JavaScript event handlers such as onerror= and onload=.
  • Unexpected outbound HTTP requests from clinician browsers to attacker-controlled domains shortly after opening a patient record.
  • Session tokens or OpenEMR cookies appearing in web server referer logs for external hosts.

Detection Strategies

  • Scan the OpenEMR image upload directory with exiftool and flag any file where metadata fields contain angle brackets, quotes, or JavaScript keywords.
  • Deploy a web application firewall rule to inspect multipart image uploads and reject files whose EXIF strings contain HTML or script syntax.
  • Review web server access logs for POST requests to the patient image upload endpoint followed by GET requests from unrelated sessions, which can indicate payload activation.

Monitoring Recommendations

  • Enable browser-side Content Security Policy reporting to capture inline script violations originating from the OpenEMR origin.
  • Audit the OpenEMR database for stored metadata fields containing suspicious character sequences and alert on anomalies.
  • Monitor authenticated session activity for sudden privilege changes or bulk record access immediately after image uploads.

How to Mitigate CVE-2025-31121

Immediate Actions Required

  • Upgrade all OpenEMR installations to version 7.0.3.1 or later without delay.
  • Restrict image upload permissions to a minimum set of trusted users until the patch is applied.
  • Review recent image uploads for malicious EXIF content and quarantine suspect files.
  • Rotate session secrets and force reauthentication for all users after remediation.

Patch Information

The OpenEMR maintainers fixed this vulnerability in version 7.0.3.1. The patch applies proper output encoding to EXIF metadata rendered in the Patient Image view. Full remediation details are available in the GitHub Security Advisory GHSA-2w94-qmj6-3qxx.

Workarounds

  • Strip EXIF metadata from uploaded images at the web server or reverse proxy layer using tools such as exiftool -all= before the file reaches OpenEMR.
  • Deploy a restrictive Content Security Policy that disallows inline scripts and limits script sources to the OpenEMR origin.
  • Temporarily disable the Patient Image feature if upgrading is not immediately possible.
bash
# Strip EXIF metadata from all images in the OpenEMR upload directory
find /var/www/openemr/sites/default/documents -type f \
  \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.tiff' \) \
  -exec exiftool -overwrite_original -all= {} \;

# Example nginx header enforcing a restrictive Content Security Policy
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'" always;

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.