All Advisories

med-united epa4all

VAU Server Authentication Bypass

epa4all integrates gematik's reference lib-vau as a git submodule and adds no verification on top. The handshake deserializes the server's signatureEs256, certHash, and ocspResponse fields without reading them, so a network attacker on the path to the ePA Aktensystem can substitute their own keys, complete the handshake, and own the resulting session.

Authored byChiara Fliegner, Volker Schönefeld, Simon WeberDisclosed 2026-05-20Fully disclosed 2026-05-28
SeverityHighCVSS 8.1CVSS 3.1 VectorAV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:HCWECWE-347 (Improper Verification of Cryptographic Signature)Productmed-united epa4allAffected Versions1.0.0-SNAPSHOT, all builds prior to the 2026-05-20 fix (initial lib-vau integration through commit `f9351df`)Fixed InPatched on 2026-05-20 (adds certificate and hostname checks for lib-vau and a keystore based on the Telematik TSL).CVECVE-2026-48021GHSAGHSA-vvh7-x6c7-46gh

Description

Defect 1: missing wrapping. VauClient.receiveMessage2() delegates directly to the reference state machine without any application-layer verification:

VauClient.java:127-128

public byte[] receiveMessage2(byte[] message2) {
return vauStateMachine.receiveMessage2(message2);
}

View source →

Defect 2: reference state machine only checks expiry. Inside the vendored lib-vau, the only check on the server's signed public keys is a temporal-validity comparison; the cryptographic signature is deserialized but never read:

VauClientStateMachine.java:104 (vendored gematik lib-vau)

VauPublicKeys transferredSignedServerPublicKeyList = signedPublicVauKeys.extractVauKeys();
checkCertificateExpired(transferredSignedServerPublicKeyList.getExp());

View source →

Status of the six A_24624-01 checks the client is required to perform on the server's signed public keys:

#A_24624-01 checkStatus in epa4all
1Certificate chain to TI PKI rootNot implemented
2OCSP response valid and currentNot implemented
3Role OID contains oid_epa_vauNot implemented
4ES256 signature on signed_pub_keysNot implemented
5ECC/Kyber key format validationImplemented (by lib-vau)
6Expiry check (exp > now)Implemented (by lib-vau)

The signatureEs256, certHash, and ocspResponse fields on SignedPublicVauKeys are deserialized into the object but never read by any verification code path in either epa4all or the vendored lib-vau. Combined with med-united: TLS Certificate Verification Disabled in epa4all, no authentication of the ePA backend exists at either the transport or the application layer.

The same gap originates upstream in the gematik reference implementations; see gematik: VAU Handshake Performs Only 2 of 6 Required Server-Key Checks for the root pattern across forks.

Impact

  • A network-positioned attacker between epa4all and the ePA Aktensystem intercepts the VAU handshake, returns self-signed VAU public keys with a self-signed certificate, and the client accepts both. The attacker derives the same K2 session keys as the client and owns the resulting encrypted channel.
  • In the production deployment model the attacker model fits the LAN. epa4all ships as an on-premise Docker container (servicehealtherxgmbh/epa4all) intended to sit in a doctor's practice; the container is reachable from the local network and connects outbound to the ePA backend.
  • A MITM holding the session keys can read and modify all inner HTTP traffic on the VAU channel: patient consent decisions, medication data, document uploads, authorization tokens, and entitlement queries. During testing, a single relay read one patient's consent decisions, swapped insurant IDs and decision values on a second response, and injected a third patient's record entirely, all from a self-signed certificate with no CA chain.

Mitigation

Update to a build dated 2026-05-20 or later. The vendor's fix adds certificate and hostname checks for lib-vau and a keystore based on the Telematik TSL, so the ES256 signature on SignedPublicVauKeys is verified against a trusted certificate from the TI PKI. No workaround exists for affected builds; transport-layer pinning alone does not authenticate the VAU server, and the parallel med-united: TLS Certificate Verification Disabled means there is no transport-layer pinning to lean on in the first place. Both fixes are required.

Defender's Checklist

  • Update to the 2026-05-20 build or later.

    All 1.0.0-SNAPSHOT builds before that date are affected. The fix adds the Telematik-TSL keystore and wires up the SignedPublicVauKeys signature check on the client side.

  • Verify the TI PKI root anchors actually load at runtime.

    The standard JVM/system trust store does not contain TI PKI roots. Confirm your deployment sources them from gemSpec_PKI's TI Root CA bundle and that the keystore is loaded before the first VAU handshake.

  • Pair this fix with the TLS verification fix.

    Even with VAU server authentication added, TLS verification across outbound connections must be re-enabled in the same build. The two fixes are independent and both required; see med-united: TLS Certificate Verification Disabled.

  • Test with a self-signed peer.

    Stand up a local VAU peer that responds to Message 2 with attacker-controlled public keys, a self-signed cert, and arbitrary signatureEs256 bytes. The client must refuse the handshake. If it does not, the validator is not wired in.

Severity Reasoning

AV:NThe threat model A_24624-01 is written against is a network attacker on the path between epa4all and the ePA Aktensystem.AC:HSubstituting keys requires active, correctly-timed interception of the live multi-message VAU handshake (Message 1 through Message 4), not a single passive request.PR:NNo credentials required beyond the network position.UI:Nepa4all initiates the VAU handshake on its own schedule; no user interaction.S:UImpact is bounded to the VAU channel and the ePA payloads it carries.C:HPlaintext access to ePA document reads, consent decisions, and metadata for any patient processed by an affected epa4all instance.I:HPlaintext access to ePA document writes, consent decisions, and authorization flows; the attacker can modify and inject responses on the inner channel.A:HAn attacker holding the session keys controls the encrypted channel and can drop or corrupt it, denying the practice access to the ePA backend.

References

How We Can Help

Who We Are

The security researchers behind this advisory.

Dr. Simon Weber Profile

Dr. rer. nat. Simon Weber

Senior Pentester & MedSec Researcher

I evaluate your SaMD with the same industry-defining security insight I contributed to the BAK MV for the revision of the B3S standard.

  • PhD on Hospital Cybersecurity
  • Critical vulnerabilities found in hospital systems
  • Alumni of THB MedSec Research Group
  • gematik Security Hero
Volker Schönefeld Profile

Dipl.-Inf. Volker Schönefeld

Senior Application Security Expert

As a former CTO and developer turned pentester, I work alongside your team to uncover vulnerabilities and find solutions that fit your architecture.

  • 20+ years as CTO, 50M+ app downloads
  • Architected and secured large-scale IoT fleets
  • Certified Web Exploitation Specialist
  • gematik Security Hero

Looking for a Penetration Test?

Machine Spirits specializes in security assessments for medical devices and healthcare IT. From MDR penetration testing to C5 cloud compliance, we help MedTech companies meet regulatory requirements.