The FHIR Validator HTTP service exposes an unauthenticated /loadIG endpoint that makes outbound HTTP requests to attacker-controlled URLs. Combined with a startsWith() URL prefix matching flaw in the credential provider (ManagedWebAccessUtils.getServer()), an attacker can steal authentication tokens (Bearer, Basic, API keys) configured for legitimate FHIR servers by registering a domain that prefix-matches a configured server URL.
Step 1 — SSRF Entry Point (LoadIGHTTPHandler.java:35-43):
The /loadIG endpoint accepts unauthenticated POST requests with a JSON body containing an ig field. The value is passed directly to IgLoader.loadIg() with no URL validation or allowlisting. When the value is an HTTP(S) URL, IgLoader.fetchFromUrlSpecific() makes an outbound GET request via ManagedWebAccess.get():
// LoadIGHTTPHandler.java:43
engine.getIgLoader().loadIg(engine.getIgs(), engine.getBinaries(), igContent, true);
// IgLoader.java:437 (fetchFromUrlSpecific)
HTTPResult res = ManagedWebAccess.get(Arrays.asList("web"), source + "?nocache=" + System.currentTimeMillis());
Step 2 — Credential Leak via Prefix Matching (ManagedWebAccessUtils.java:14):
When ManagedWebAccess creates a SimpleHTTPClient, it attaches an authProvider that uses startsWith() to determine whether credentials should be sent:
// ManagedWebAccessUtils.java:14
if (url.startsWith(serverDetails.getUrl()) && typesMatch(serverType, serverDetails.getType())) {
return serverDetails;
}
If the server has https://packages.fhir.org configured with a Bearer token, a request to https://packages.fhir.org.attacker.com/... matches the prefix, and the token is attached to the request to the attacker's domain.
Step 3 — Redirect Amplification (SimpleHTTPClient.java:84-99,111-118):
SimpleHTTPClient manually follows redirects with setInstanceFollowRedirects(false). On each redirect hop, getHttpGetConnection() calls...
6.9.4Exploitability
AV:NAC:LPR:NUI:NScope
S:CImpact
C:HI:LA:N9.3/CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:N