Alle Sicherheitshinweise

mercure

SQL Injection in den Bookkeeper-Abfrage-Endpunkten

Der Bookkeeper von mercure baut SQL-Abfragen, indem er Request-Parameter per Python-f-String in den Abfragestring interpoliert, ohne Parametrisierung. Der Parameter task_id ist über den API-Proxy der Weboberfläche für jeden authentifizierten Benutzer erreichbar, sodass ein authentifiziertes Konto über Blind SQL Injection beliebige Daten aus der Datenbank lesen kann, einschließlich gespeicherter Patientendaten.

Verfasst vonVolker Schönefeld, Simon Weber2026-05-30
SchweregradMittelCVSS 6.5CVSS-3.1-VektorAV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:NCWECWE-89 (SQL Injection)ProduktmercureBetroffene VersionenAlle Releases von 0.2.0-beta.1 bis 0.4.0-beta.9.Behoben in0.4.1. Die Bookkeeper-Abfragen nutzen gebundene Parameter für task_id und die Zeitzonen-Klausel, und der Wert der Sortierrichtung wird gegen eine Allowlist validiert.CVEAusstehendGHSAAusstehend

Beschreibung

mercure ist eine quelloffene DICOM-Orchestrierungsplattform; wir schätzen die schnelle, konstruktive Reaktion der Maintainer auf diesen Bericht. Der Bookkeeper speichert Task- und Serien-Metadaten in einer PostgreSQL-Datenbank und stellt Abfrage-Endpunkte bereit, die von der Weboberfläche genutzt werden.

Der Query-Parameter task_id wird per f-String direkt in die SQL-WHERE-Klausel interpoliert, ohne Parametrisierung:

app/bookkeeping/query.py:117-150

@router.get("/task-events")
@requires("authenticated")
async def get_task_events(request) -> JSONResponse:
task_id = request.query_params.get("task_id", "") # unbereinigt
# ...
query_string = f"""select *, time {tz_conversion} as local_time from task_events
where task_events.task_id = '{task_id}' {subtask_ids_filter}
order by task_events.task_id, task_events.time
"""
query = sqlalchemy.text(query_string)
results = await db.database.fetch_all(query)

View source →

Der Endpunkt ist über den API-Proxy der Weboberfläche (/api/get-task-events?task_id=...) für jeden authentifizierten Benutzer erreichbar, der den Parameter unverändert weiterleitet. Zwei weitere Senken existieren: die ORDER BY-Richtung (ebenfalls aus einem Request-Parameter) und die Zeitzonen-Klausel (aus gespeicherter Admin-Konfiguration).

Da der Wert unmaskiert in der Abfrage landet, kann ein authentifizierter Benutzer mit error-based und time-based Blind Injection beliebige Tabellen Bedingung für Bedingung pro Anfrage auslesen. Wir veröffentlichen keinen funktionsfähigen Payload.

Die Tabelle dicom_series enthält Patientendaten: Patientenname, Patienten-ID, Geburtsdatum, Accession Number und überweisender Arzt. Der Proof of Concept zählt das Schema auf, bestätigt diese Spalten und dass Patientendatensätze vorhanden sind:

Proof-of-Concept-Ausgabe

Datenbank: PostgreSQL 14.0 (user=mercure, db=mercure)
Tabellen: task_events, tasks, dicom_series, dicom_files, ...
dicom_series-Spalten: tag_patientname, tag_patientid,
tag_patientbirthdate, tag_accessionnumber, tag_referringphysicianname
Patientendatensätze vorhanden.

Auswirkung

  • Jeder authentifizierte Benutzer, auch ein Nicht-Admin, kann über Blind SQL Injection beliebige Daten aus der Bookkeeper-Datenbank lesen.
  • Dazu gehört die Tabelle dicom_series, die Patientendaten speichert (Name, ID, Geburtsdatum, Accession Number). Ein Nicht-Admin-Konto kann somit Datensätze aus dieser Tabelle lesen, die es nie sehen sollte.
  • Gestapelte Schreibabfragen sind über diesen Treiber nicht verfügbar, sodass die Auswirkung Lesezugriff auf die Datenbank ist, keine Änderung.
  • Für ein Krankenhaus oder eine Klinik bedeutet das: Jedes Personal mit einem mercure-Login kann die gespeicherten Patientendaten-Datensätze lesen, unabhängig von der zugewiesenen Rolle.

Abhilfe

Aktualisieren Sie auf mercure 0.4.1, das gebundene Parameter für task_id und die Zeitzonen-Werte nutzt und die Sortierrichtung gegen eine Allowlist validiert. Allgemein SQL mit Parameterbindung statt String-Interpolation bauen, was die übliche Lösung für dieses Muster ist.

Checkliste für Betreiber

  • Auf 0.4.1 oder neuer aktualisieren

    Das gepatchte Release ausrollen, das die Bookkeeper-Abfragen parametrisiert.

  • Datenbankzugriff prüfen

    Bei Verdacht auf Offenlegung die Bookkeeper-Abfrage-Logs auf anomale task_id-Werte prüfen.

  • Konten begrenzen

    Begrenzen, wer mercure-Konten besitzt; in betroffenen Versionen kann jedes authentifizierte Konto diesen Endpunkt erreichen.

Bewertung im Detail

AV:NDer Abfrage-Endpunkt wird über das Netzwerk über den API-Proxy der Weboberfläche erreicht.AC:LJeder bedingte Lesevorgang ist eine einzige Anfrage; keine besonderen Bedingungen.PR:LEin beliebiges authentifiziertes Konto genügt; Admin ist nicht erforderlich.UI:NKeine Benutzerinteraktion.S:UDie Auswirkung bleibt im Datenbank-Scope des Bookkeepers.C:HBeliebiger Datenbank-Lesezugriff, einschließlich Patientendaten.I/A:NDer Treiber erlaubt über diesen Pfad keine gestapelten Schreibabfragen, sodass Integrität und Verfügbarkeit nicht betroffen sind.

Referenzen

So können wir helfen

Wer wir sind

Die Sicherheitsforscher hinter diesem Sicherheitshinweis.

Dr. Simon Weber Profile

Dr. rer. nat. Simon Weber

Senior Pentester & MedSec-Forscher

Ich evaluiere Ihr SaMD mit derselben branchenprägenden Sicherheitsexpertise, die ich dem BAK MV für die Überarbeitung des B3S-Standards beigetragen habe.

  • Promotion über Krankenhaus-Cybersicherheit
  • Kritische Schwachstellen in Krankenhaussystemen gefunden
  • Alumni der THB MedSec-Forschungsgruppe
  • gematik Security Hero
Volker Schönefeld Profile

Dipl.-Inf. Volker Schönefeld

Senior Application Security Expert

Als ehemaliger CTO und Entwickler, der zum Pentester wurde, arbeite ich mit Ihrem Team zusammen, um Schwachstellen aufzudecken und Lösungen zu finden, die zu Ihrer Architektur passen.

  • 20+ Jahre als CTO, 50+ Mio. App-Downloads
  • Architektur und Absicherung großer IoT-Flotten
  • Certified Web Exploitation Specialist
  • gematik Security Hero

Penetrationstest gesucht?

Machine Spirits ist spezialisiert auf Sicherheitsbewertungen für Medizinprodukte und Gesundheits-IT. Von MDR-Penetrationstests bis C5-Cloud-Compliance helfen wir MedTech-Unternehmen, regulatorische Anforderungen zu erfüllen.