Alle Sicherheitshinweise

fbeta ePA3-Service-OpenSource

HTTP-Header-Injection in den inneren VAU-Requests

fbetas ePA3-Service baut innere VAU-HTTP-Requests durch f-String-Interpolation vom Aufrufer kontrollierter Werte (KVNR insurantId, Umgebungsvariable USER_AGENT, Argument boundary_string) direkt in rohe Header-Zeilen, womit die CRLF-Validierung der requests-Bibliothek umgangen wird. Ein authentisierter DiGA-Nutzer kann durch eine KVNR mit eingebettetem CRLF einen zweiten x-insurantid-Header in den verschlüsselten VAU-Kanal einschleusen.

SchweregradMittelCVSS 6.8CVSS-3.1-VektorAV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:NCWECWE-113 (Improper Neutralization of CRLF Sequences in HTTP Headers)Produktfbeta ePA3-Service-OpenSourceBetroffene VersionenAlle Versionen vor 1.3.0 (vom initialen Commit `a61f91d` bis einschließlich 1.0.1)Behoben in1.3.0 (enthält Pull Request #11)GHSAGHSA-j8jg-7fqf-4xx9

Beschreibung

Alle vier Methoden, die innere VAU-HTTP-Requests bauen, interpolieren vom Aufrufer kontrollierte Parameter direkt per f-String in rohe HTTP-Header und kodieren den zusammengesetzten Request als UTF-8-Bytestring für die AES-GCM-Verschlüsselung. Die requests-Bibliothek, die CRLF in Header-Werten ablehnt, wird vollständig umgangen; an keiner Stelle der inneren Request-Konstruktion findet CRLF-Bereinigung statt.

VAUProtokoll.py:507-515 (Muster wiederholt sich in allen 4 Methoden)

inner_request = "GET /epa/authz/v1/getNonce HTTP/1.1\r\n"
inner_request += f"Host: {self.host}\r\n"
inner_request += "Accept: application/json\r\n"
inner_request += "Content-Type: application/json\r\n"
inner_request += f"x-useragent: {USER_AGENT}\r\n"
inner_request += f"x-insurantid: {insurant_id}\r\n"
inner_request += "\r\n"
inner_request = inner_request.encode("utf-8")

View source →

Einschleusbare Parameter:

Einschleusbare Parameter

insurant_id : metadata['insurantId'], nur als JSON-Schema-String validiert
USER_AGENT : os.getenv('USER_AGENT'); vergiftet jeden Request der Session
boundary_string : vom Aufrufer in upload_document() geliefert; Content-Type-Breakout
self.host : Host-String des Servers in jedem Request

Die vier betroffenen Methoden sind get_nonce() (507-515), send_authorization_request_sc() (542-552), send_authcode_sc() (634-644) und upload_document() (688-698). Der Wert von insurantId stammt aus dem metadata['insurantId']-Feld der DiGA, das ausschließlich als "type": "string" validiert wird, ohne Muster-Vorgabe; das KVNR-Format ist strikt [A-Z][0-9]{9}, doch das JSON-Schema setzt es nicht durch.

Während eines Testlaufs wurde eine KVNR mit eingebettetem CRLF (X123456789\r\nX-Injected: ...) über die DiGA-Schnittstelle geliefert. Der Relay entschlüsselte den inneren HTTP-Verkehr und beobachtete, wie beide Header in die innere Verarbeitung des ePA-Servers gelangten:

Entschlüsselter innerer HTTP-Verkehr nach CRLF-Injection

Decrypted inner HTTP (REQUEST):
GET /epa/authz/v1/getNonce HTTP/1.1
Host: epa-as-2.dev.epa4all.de
Accept: application/json
Content-Type: application/json
x-useragent: usrAgent/1.1.0
x-insurantid: X000000000
X-Injected: CRLF-header-injection-confirmed
CRLF in insurantId passed through to inner HTTP.
f-string interpolation, no sanitization.

Auswirkung

  • Cross-Patient-Datenoffenlegung: Das Einschleusen eines zweiten x-insurantid-Headers mit einer anderen KVNR kann je nach Header-Vorrangs-Verhalten des ePA-Servers (first-wins vs. last-wins) dazu führen, dass Datensätze einer anderen Versicherten zurückgegeben werden.
  • Autorisierungs-Bypass: Ein eingeschleuster Authorization: Bearer <token>-Header könnte den normalen Authentifizierungsfluss im inneren HTTP-Handler des ePA-Servers umgehen.
  • Sitzungsweites Poisoning: Eine bösartige USER_AGENT-Umgebungsvariable schleust für die gesamte Sitzungslaufzeit Header in jeden inneren HTTP-Request ein.
  • Request-Smuggling: In send_authcode_sc() wird der Content-Length-Header aus len(body_json) berechnet, bevor eine Injection greifen kann; wenn eingeschleuste Daten die Header-Body-Grenze verschieben, entsteht eine HTTP-Desync-Angriffsfläche.
  • Wenn auch der gematik: VAU-Handshake führt nur 2 von 6 vorgeschriebenen Server-Schlüssel-Prüfungen aus oder fbeta: VAU-Server-Authentifizierungs-Bypass durch zirkuläres Zertifikatsvertrauen unmitigiert ist, kontrolliert ein MITM die innere VAU-Klartext-Ebene ohne DiGA-Nutzer-Privileg; der eingeschleuste x-insurantid kommt per Relay statt durch einen authentisierten Request, und PR sinkt auf N.

Abhilfe

Aktualisieren Sie fbeta ePA3-Service-OpenSource auf 1.3.0 oder höher. Der Fix bereinigt jeden vom Aufrufer kontrollierten Wert vor der Interpolation (jede Zeichenkette mit \r oder \n wird abgelehnt) und validiert insurantId an der Bibliotheksgrenze gegen das KVNR-Format ^[A-Z]\d{9}$. Die längerfristige Behebung im PR ersetzt die manuelle String-Zusammensetzung innerer HTTP-Requests durch eine Bibliothek, die Header-Validierung, korrekte Content-Length-Berechnung und passende Kodierung mitbringt.

Checkliste für Betreiber

  • Auf fbeta ePA3-Service-OpenSource 1.3.0 oder höher aktualisieren.

    Alle Versionen vor 1.3.0 sind betroffen. Der Fix liegt in Pull Request #11.

  • KVNR an der DiGA-Grenze validieren, nicht erst in der Bibliothek.

    Das KVNR-Format ^[A-Z]\d{9}$ ist strikt definiert. Wenden Sie die Regex am frühesten Punkt an, an dem der Wert Ihre Vertrauensgrenze überschreitet (Formulareingabe, API-Request-Body), damit eine ungültige KVNR scheitert, bevor sie diese Bibliothek erreicht.

  • Umgebungsvariablen prüfen.

    Die USER_AGENT-Umgebungsvariable war ein Poisoning-Vektor: Ein Wert mit CRLF vergiftete jeden Request der Sitzungslaufzeit. Wenn Ihr Deployment weitere Umgebungsvariablen in innere HTTP-Header übernimmt, validieren Sie sie beim Start, nicht zum Zeitpunkt der Verwendung.

  • Kein HTTP per Hand zusammenbauen.

    Wo Sie den Code selbst kontrollieren, ersetzen Sie manuelle inner_request += f"..."-Muster durch eine Bibliothek, die eine wohlgeformte HTTP-Nachricht produziert. Der Fehler hier wäre nicht möglich gewesen, wenn Header-Werte zwischen Aufrufer und Verschlüsselungsschritt eine Validierungsschicht durchlaufen hätten.

Bewertung im Detail

AV:NDer Injection-Vektor ist das KVNR-Feld in einem DiGA-Request, über die DiGA-Schnittstelle übers Netz erreichbar.AC:HErfordert, dass der innere HTTP-Handler des ePA-Servers einen duplizierten x-insurantid (oder einen anderen eingeschleusten Header) so honoriert, dass Datensätze zurückgegeben oder modifiziert werden; nicht in jeder Server-Konfiguration garantiert. AC:H trägt die Unsicherheit des serverseitigen Schritts.PR:LEin authentisierter DiGA-Nutzer wird benötigt, um die bösartige KVNR über die DiGA-Schnittstelle einzubringen.UI:NKeine Interaktion eines zweiten Beteiligten erforderlich.S:UDie Auswirkung ist auf Datensätze beschränkt, die über den inneren HTTP-Handler des ePA-Servers erreichbar sind.C:HWorst-Case-Cross-Patient-Datenoffenlegung, wenn ein duplizierter x-insurantid dazu führt, dass Datensätze einer anderen Betroffenen zurückgegeben werden. Die serverseitige Header-Vorrangs-Logik ist der unsichere Schritt, getragen von AC:H; fbeta selbst bewertet den gleichen Vektor in ihrem GHSA.I:HWorst-Case-Modifikation der Semantik des inneren HTTP-Requests durch Autorisierungs-Bypass und Request-Smuggling. Das abhängige serverseitige Verhalten ist der unsichere Schritt, getragen von AC:H.A:NKeine Auswirkung auf die Verfügbarkeit.

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.