Résumé
HAPI FHIR: SHCParser DEFLATE infinite loop causes denial of service
Détails de l’avis
Summary
A malformed Smart Health Card (SHC) JWT with zip: "DEF" and an empty or truncated DEFLATE payload causes SHCParser.inflate() to loop forever. This allows an attacker who can submit SHC content for validation to pin a JVM worker thread indefinitely, causing denial of service.
Details
The vulnerable code is in org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHCParser.java.
decodeJWT() inflates the JWT payload when the header contains "zip":"DEF":
// SHCParser.java:300-302
if ("DEF".equals(res.header.asString("zip"))) {
payloadJson = inflate(payloadJson);
}
inflate() loops only on !inflater.finished() and does not check inflater.needsInput(), inflater.needsDictionary(), or zero-progress output:
// SHCParser.java:455-468
while (!inflater.finished()) {
final int count = inflater.inflate(buffer);
outputStream.write(buffer, 0, count);
}
For empty or truncated raw DEFLATE input, Inflater.inflate() returns 0, finished() remains false, and needsInput() becomes true, producing an infinite tight loop. The same unsafe loop pattern also exists in decompress() at SHCParser.java:410-423.
The validator reaches this path during SHC validation and during file-format detection for SHC-looking input (ResourceChecker.java:115-118).
PoC
Compile the project, then run a minimal local harness that calls:
SHCParser.inflate(new byte[0]);
This never returns. Local verification:
timeout 3s java -cp ... VerifyDoSFindings shcHang
echo $?
# 124 = timeout killed the hung process
A JWT PoC uses:
- header: Base64URL(
{"zip":"DEF"}) - payload: empty or truncated raw DEFLATE bytes
- signature: arbitrary
Submit the resulting token as SHC content, for example via a .shc file or content beginning with shc:/ that reaches the validator's SHC detection path.
Impact
This is a denial-of-service vulnerability. A single malformed SHC validation request can consume a worker thread indefinitely. In services that validate uploaded SHC content, a small number of concurrent malformed requests can exhaust all validation workers.
Credits
- Thai Son Dinh from VinSOC Labs (R&D)
Références
- https://github.com/advisories/GHSA-gq9c-wmrm-5hvr
- https://github.com/hapifhir/org.hl7.fhir.core/security/advisories/GHSA-gq9c-wmrm-5hvr
- https://nvd.nist.gov/vuln/detail/CVE-2026-81876
- https://github.com/hapifhir/org.hl7.fhir.core/pull/2493
- https://github.com/hapifhir/org.hl7.fhir.core/commit/d804558bd77372b1629e55a5b901cad3f5134cdc
- https://github.com/hapifhir/org.hl7.fhir.core/commit/edd5d8c139e669e39270785f08be7b63aefef24c
Vulnérabilités liées
Tout Supply chain →- MEDIUMCVE-2026-48484
pyLoad: Lack of Input Size Validation Leads to Denial of Service (DoS) and Process Termination
- MEDIUMCVE-2026-107391
music-metadata: MP4 stsd sample-entry size==0 causes a synchronous infinite loop (DoS) — unreleased regression on master
- HIGHGHSA-6w6g-hm98-mhgm
hickory-resolver: Unbounded TC-retry loop in `NameServerPool::try_send` (resource-exhaustion DoS)
- HIGHCVE-2026-101895
Angular SSR: Denial of Service (DoS) via Infinite Loop on Malformed DOCTYPE
- HIGHCVE-2026-81875
HAPI FHIR: SHCParser unbounded DEFLATE decompression causes denial of service
- HIGHCVE-2026-68523
Fulgur: Unbounded page slicing from attacker-controlled CSS height causes denial of service