OpenEMR: SQL Injection im Dokument-API des Patientenportals

Jeder angemeldete Portal-Patient liest über den Parameter Id_BitwiseAnd die gesamte Datenbank, darunter die Daten anderer Patienten und die Passwort-Hashes der Admin-Konten.

Advisory-ID: TP-2026-118
Produkt: OpenEMR (Praxis- und Patientenverwaltung mit Patientenportal)
Schwachstellentyp: SQL Injection (CWE-89)
CVE: beantragt (GitHub CNA), Vergabe ausstehend
CVSS 3.1: 7.7 (Hoch) · CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N
Betroffene Versionen: < 8.5.0
Hersteller-Advisory: GHSA-g2xw-rvhq-x543
Behoben in: 8.5.0
Gemeldet: 13. Juni 2026

Zusammenfassung

OpenEMR ist eine quelloffene Software für elektronische Patientenakten mit einem Patientenportal, über das Patienten ihre eigenen Dokumente abrufen. Der Dokument-Endpunkt OnsiteDocument.Query überträgt Request-Parameter ungeprüft auf das Phreeze-Criteria-Objekt, darunter den Operator Id_BitwiseAnd. Dessen Wert landet ohne Anführungszeichen im SQL, und die Maskierung des Frameworks entschärft nur Anführungszeichen. Jeder angemeldete Portal-Patient liest so die gesamte Datenbank, einschließlich der Daten anderer Patienten und der Passwort-Hashes aller Mitarbeiter- und Admin-Konten.

Ursache

OnsiteDocumentController::Query() kopiert jeden $_REQUEST-Schlüssel, dessen ucfirst()-Name einer Criteria-Eigenschaft entspricht, direkt auf das Objekt (portal/patient/libs/Controller/OnsiteDocumentController.php:144). Die generierte Criteria-Klasse deklariert für jede Spalte eine Eigenschaft <Feld>_BitwiseAnd (portal/patient/libs/Model/DAO/OnsiteDocumentCriteriaDAO.php), sodass ein Parameter Id_BitwiseAnd zuweisbar ist und Criteria::GetWhere() erreicht. GetWhere() baut daraus (<spalte> & <wert>) und fügt den Wert über Escape() ohne umschließende Anführungszeichen ein (portal/patient/fwk/libs/verysimple/Phreeze/Criteria.php:275). Escape() ersetzt nur \ \0 \n \r \x1a ' " (portal/patient/fwk/libs/verysimple/DB/DataDriver/MySQLi.php:166), Leerzeichen, Klammern und SQL-Schlüsselwörter bleiben erhalten, während die Geschwister-Operatoren _Equals und _IsLike ihren Wert in Anführungszeichen setzen. Die Route api/onsitedocuments trägt p_acl => p_all (portal/patient/_app_config.php:168) und ist damit für jeden Portal-Patienten erreichbar, und die eingeschleuste Bedingung wirkt außerhalb der patientenbezogenen Einschränkung Pid_Equals.

Proof of Concept

GET /portal/patient/api/onsitedocuments?Id_BitwiseAnd=0 OR extractvalue(1,concat(0x7e,(SELECT substr(password,1,28) FROM users_secure WHERE username=0x61646d696e)))
Cookie: PortalOpenEMR=<portal-session>

-> {"message":"... XPATH syntax error: '~$2y$12$DmBtGQqVm15ft78eILY9S' ..."}

Der Wert von Id_BitwiseAnd bricht aus dem numerischen Kontext aus, und die Fehlermeldung der Datenbank gibt das Ergebnis der Unterabfrage zurück. Auf demselben Weg liest der Portal-Patient Name und Adresse anderer Patienten aus patient_data.

Auswirkung

  • Offenlegung der Gesundheits- und Stammdaten aller Patienten an jeden Portal-Patienten, an der patientenbezogenen Einschränkung Pid_Equals vorbei.
  • Offenlegung der Passwort-Hashes aller Mitarbeiter- und Admin-Konten aus users_secure, offline angreifbar bis zum OpenEMR-Administrator.
  • Lesezugriff auf das übrige openemr-Schema mit derselben Primitive, darunter Sitzungen, OAuth- und API-Token sowie das Audit-Log.
  • Ausgelöst durch die niedrigste legitime Rolle mit einer einzigen Anfrage, ohne Mitwirkung eines Opfers.

Referenzen

Steckt so etwas in Ihrer Software?

Diese Schwachstelle hat unser Team im Rahmen seiner Arbeit gefunden. Lassen Sie Ihre Anwendungen von denselben Spezialisten prüfen, mit einem Penetrationstest von turingpoint.