CVE-2026-50576 Overview
CVE-2026-50576 is a CRLF (Carriage Return Line Feed) injection vulnerability [CWE-113] in the ePA 3.x Integration component that writes Medical Information Objects to Germany's electronic patient record system. The flaw resides in app/vau/VAUProtokoll.py, where the build_inner_header function interpolates user-controlled values into VAU inner HTTP request lines and headers without neutralizing CRLF characters. An authenticated attacker can inject additional headers, including x-insurantid and Authorization, into the inner request. The issue is fixed in version 1.3.0.
Critical Impact
An authenticated attacker can inject x-insurantid or Authorization headers into VAU inner HTTP requests to access other patients' medical records or bypass authorization.
Affected Products
- ePA 3.x Integration prior to version 1.3.0
- app/vau/VAUProtokoll.py component (build_inner_header function)
- Deployments writing to Germany's electronic patient record (elektronische Patientenakte)
Discovery Timeline
- 2026-08-18 - CVE-2026-50576 published to NVD
- 2026-08-18 - Last updated in NVD database
Technical Details for CVE-2026-50576
Vulnerability Analysis
The vulnerability stems from unsanitized input flowing into HTTP header construction inside the VAU (Vertrauenswürdige Ausführungsumgebung) protocol layer. The build_inner_header function interpolates seven values into request lines and headers: uri, host, accept_type, content_type, content_length, USER_AGENT, and insurant_id. These values populate request lines and custom headers such as x-useragent and x-insurantid.
Because CRLF sequences (\r\n) are not stripped or rejected, an authenticated caller who controls any interpolated value can terminate the current header line and append arbitrary headers. Depending on how the downstream ePA server processes duplicated or last-wins headers, an injected x-insurantid header can redirect the request to another patient's records. Injected Authorization headers can override the authentication context. The USER_AGENT field is derived from session state, so a single poisoned value can affect subsequent requests within the session.
Root Cause
The root cause is missing input validation on values used to build HTTP headers. String interpolation was used directly without checking for \r, \n, or \\x00 characters, and without validating format-constrained fields such as the insurant identifier.
Attack Vector
Attackers must authenticate to the ePA 3.x Integration service and control at least one field that reaches build_inner_header. The attacker submits a request containing CRLF-encoded content in a controlled field, causing the constructed inner request to carry attacker-chosen headers when relayed inside the VAU tunnel.
# Security patch in app/vau/utils.py
# Source: https://github.com/fbeta-GmbH/ePA3-Service-OpenSource/commit/b984d15d261423302de337adae25e84c54e9c2d1
import json
import re
from app.exceptions import ErrorCodes, DocumentException, AuthorizationException
from fastapi import status
def sanitize_header_value(value: str) -> str:
if '\r' in value or '\n' in value or '\\x00' in value:
raise ValueError("Invalid header value: contains CRLF or NUL characters")
return value
def validate_insurant_id(insurant_id: str) -> str:
if not re.match(r'^[A-Z]\d{9}$', insurant_id):
raise ValueError(f"Invalid Insurant ID format: {insurant_id}")
return insurant_id
The patch introduces sanitize_header_value to reject CRLF and NUL bytes, plus validate_insurant_id to enforce the expected format of a leading capital letter followed by nine digits.
Detection Methods for CVE-2026-50576
Indicators of Compromise
- Inner VAU HTTP requests containing duplicated x-insurantid, x-useragent, or Authorization headers.
- Request payloads or session fields containing URL-encoded %0d%0a or raw \r\n byte sequences in uri, host, USER_AGENT, or insurantId values.
- Access log entries where the acting session identifier does not correspond to the insurantId returned in retrieved records.
Detection Strategies
- Inspect application logs from app/vau/VAUProtokoll.py for header values containing control characters before the 1.3.0 upgrade.
- Diff observed insurantId values against the regex ^[A-Z]\d{9}$ and alert on any that fail the pattern.
- Correlate authenticated session identifiers with the patient records returned by the ePA backend to surface cross-patient access.
Monitoring Recommendations
- Enable verbose request logging around build_inner_header invocations and forward events to a centralized log platform for analysis.
- Alert on any inner request that carries more than one occurrence of x-insurantid, x-useragent, or Authorization.
- Track anomalous USER_AGENT values persisted in session state, especially values that change mid-session.
How to Mitigate CVE-2026-50576
Immediate Actions Required
- Upgrade ePA 3.x Integration to version 1.3.0 or later, which introduces sanitize_header_value and validate_insurant_id.
- Rotate any session tokens issued before the upgrade, since session-derived USER_AGENT values may have been poisoned.
- Audit access logs for the presence of duplicated identity or authorization headers on VAU inner requests.
Patch Information
The fix is available in ePA 3.x Integration release 1.3.0. The patch merged via pull request #11 and is documented in GHSA-j8jg-7fqf-4xx9 and the Machine Spirits advisory #013a60.
Workarounds
- If upgrading immediately is not feasible, wrap all values passed to build_inner_header with a validator that rejects \r, \n, and \\x00.
- Enforce the insurant identifier regex ^[A-Z]\d{9}$ at the API boundary before values reach VAU protocol construction.
- Restrict authenticated API access to trusted clients and reduce session lifetime to limit the persistence of poisoned USER_AGENT state.
# Configuration example: verify installed version and pin to the fixed release
pip show epa3-service | grep -i version
pip install --upgrade 'epa3-service==1.3.0'
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

