Alle Sicherheitshinweise

mercure

Beliebige Docker-Container-Konfiguration führt zur Host-Kompromittierung

mercure betreibt seine Verarbeitungsmodule als Docker-Container. Die Modulkonfiguration enthält ein Feld docker_arguments, dessen JSON ohne Validierung direkt als Keyword-Argumente an die Docker-API übergeben wird. Ein Administrator kann daher Container-Optionen wie den privilegierten Modus oder eine Einbindung des Host-Dateisystems setzen, über eine passende Regel einen Container starten und zum Docker-Host ausbrechen. Dies überschreitet die Grenze zwischen dem Anwendungsadministrator (jedem Inhaber einer Admin-Sitzung in der mercure-Weboberfläche) und dem Infrastruktur-Administrator (dem IT-Team, dem der Host gehört).

Verfasst vonVolker Schönefeld, Simon Weber2026-05-30
SchweregradKritischCVSS 9.1CVSS-3.1-VektorAV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:HCWECWE-250 (Execution with Unnecessary Privileges)ProduktmercureBetroffene VersionenAlle Releases von 0.2.0-beta.1 bis 0.4.0-beta.9.Behoben in0.4.1. Der Konfigurationseditor lehnt nun gefährliche docker_arguments und Volume-Mounts ab, und Verarbeitungscontainer verwenden standardmäßig cap_drop: ["ALL"] und network_mode: "none".CVEAusstehendGHSAAusstehend

Beschreibung

mercure ist eine quelloffene DICOM-Orchestrierungsplattform; wir schätzen die schnelle, konstruktive Reaktion der Maintainer auf diesen Bericht. mercure betreibt jedes Verarbeitungsmodul als Docker-Container, wofür der Prozessor einen Docker-Socket besitzen muss. Dieser Socket ist architektonisch vorgegeben; das Problem ist, was die Weboberfläche einen Administrator hindurchgeben lässt.

Die Modulkonfiguration enthält ein Feld docker_arguments. Sein Wert wird unverändert gespeichert, ohne Validierung. Die Felder contact und comment werden bereinigt; die Docker-steuernden Felder nicht:

app/webinterface/modules.py:58-81

async def save_module(form, name) -> None:
config.mercure.modules[name] = Module(
docker_tag=form.get("docker_tag", "").strip(),
additional_volumes=form.get("additional_volumes", ""),
environment=form.get("environment", ""),
docker_arguments=form.get("docker_arguments", ""),
settings=new_settings,
contact=strip_untrusted(form.get("contact", "")),
comment=strip_untrusted(form.get("comment", "")),
# ...
)
config.save_config()

View source →

Zur Laufzeit wird das gespeicherte JSON dekodiert und als Keyword-Argumente in containers.run() des Docker-SDK gesplattet:

app/process/process_series.py:268-278

arguments = decode_task_json(module.docker_arguments)
# ...
container = docker_client.containers.run(
docker_tag,
mounts=default_mounts,
volumes=additional_volumes,
environment=environment,
**runtime,
**set_command,
**arguments, # beliebige kwargs aus Admin-Eingabe
**user_info,
detach=True,
)

View source →

Damit lässt sich jede Docker-Run-Option setzen. Keine davon wird vom bestehenden Code gesetzt, sodass sie sauber durch das Keyword-Splatting gelangen. Einige, die dem Container die Kontrolle über den Host geben:

Docker-ArgumentWirkung
privileged: trueVolle Host-Capabilities, alle Geräte, kein seccomp/AppArmor
pid_mode: "host"Container sieht und beeinflusst alle Host-Prozesse
network_mode: "host"Container teilt den Host-Netzwerk-Namespace
Host-Bind-MountBindet das Host-Dateisystem in den Container ein

Ein Administrator setzt solche Argumente an einem Modul, verknüpft es mit einer Regel, die eingehende Serien matcht, und eine passende DICOM-Serie startet den Container. Aus einem privilegierten oder host-gemounteten Container ist das Erreichen von Host-Root ein Standardschritt, den wir hier nicht reproduzieren. Verkettet mit der Rechteausweitung durch fehlende Autorisierung oder den Standard-Anmeldedaten admin:router erreicht ein geringer privilegierter oder nicht authentifizierter Zugang Host-Root.

Der Proof of Concept bestätigt, dass ein privilegierter Container auf dem Host-Daemon gestartet wird:

Proof-of-Concept-Ausgabe

Privileged=true PidMode=host NetworkMode=bridge

Auswirkung

  • Ein mercure-Anwendungsadministrator (jeder Benutzer mit einer Administrator-Sitzung in der Weboberfläche) kann sich zu Root auf dem Docker-Host ausweiten. Ein privilegierter oder host-gemounteter Container, der über eine passende Regel gestartet wird, gibt vollständige Kontrolle über das Host-Betriebssystem.
  • Host-Zugriff legt das klinische Netzwerk, Anmeldedaten und Schlüssel für andere Dienste sowie etwaige Patientendaten auf gemeinsam genutztem Speicher offen.
  • Verkettet mit der Rechteausweitung durch fehlende Autorisierung oder den Standard-Anmeldedaten admin:router erreicht ein geringerer oder nicht authentifizierter Zugang die vollständige Host-Kompromittierung.

Abhilfe

Aktualisieren Sie auf mercure 0.4.1, das gefährliche docker_arguments und Volume-Mounts ablehnt und Container-Standardwerte verschärft (cap_drop: ["ALL"], network_mode: "none"). Die allgemeine Lösung für diese Konstruktion: benutzergelieferte Werte niemals direkt an eine Container-Laufzeit übergeben, sondern die von einem Anwendungsadministrator setzbaren Docker-Argumente per Allowlist beschränken (Ressourcenlimits, Labels), Volume-Mounts auf die konfigurierten Datenverzeichnisse begrenzen und Images auf eine vertrauenswürdige Registry beschränken.

Checkliste für Betreiber

  • Auf 0.4.1 oder neuer aktualisieren

    Das gepatchte Release ausrollen, das gefährliche Docker-Argumente und Volume-Mounts standardmäßig ablehnt.

  • Modulkonfigurationen prüfen

    docker_arguments und additional_volumes in mercure.json auf Optionen wie privileged, pid_mode, Host-Netzwerk oder Host-Pfad-Mounts prüfen.

  • Die Rollen trennen

    Den mercure-Web-Administrator und den Docker-Host-Administrator als unterschiedliche Vertrauensstufen behandeln; begrenzen, wer Module anlegen oder bearbeiten darf.

Bewertung im Detail

AV:NModul- und Regelkonfiguration erfolgt über das Netzwerk über die Weboberfläche; der Container startet bei einer über das Netzwerk gelieferten DICOM-Serie.AC:LDas Setzen der Argumente und einer passenden Regel genügt.PR:HDie Modulkonfiguration erfordert eine Administrator-Sitzung.UI:NDer Container startet automatisch beim Eintreffen einer passenden Serie.S:CDer gestartete Container bricht aus dem mercure-Scope aus und kontrolliert den Docker-Host und alles darauf.C/I/A:HHost-Root gewährt vollständigen Lese-, Änderungs- und Verweigerungszugriff über den Host und benachbarte Systeme.

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.