Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-81876

CVE-2026-81876: HAPI FHIR Smart Health Card DOS Vulnerability

CVE-2026-81876 is a denial of service vulnerability in HAPI FHIR that allows attackers to trigger infinite loops through malformed Smart Health Card JWT content. This article covers technical details, affected versions, and mitigation.

Published:

CVE-2026-81876 Overview

CVE-2026-81876 is a denial-of-service vulnerability in HAPI FHIR, the Java implementation of the HL7 FHIR standard for healthcare interoperability. The flaw resides in SHCParser within org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHCParser.java. When the parser processes attacker-controlled Smart Health Card (SHC) JWT content declaring zip: "DEF" with an empty or truncated raw-DEFLATE payload, the inflation loop fails to terminate. A single malformed validation request can pin a JVM worker thread indefinitely, and concurrent requests can exhaust all validation workers. The issue is fixed in version 6.9.12.

Critical Impact

Unauthenticated network attackers can exhaust FHIR validation worker threads and render the service unavailable by submitting malformed Smart Health Card content.

Affected Products

  • HAPI FHIR (org.hl7.fhir.core) versions prior to 6.9.12
  • The org.hl7.fhir.r5 module containing SHCParser
  • Applications invoking ResourceChecker for file-format detection

Discovery Timeline

  • 2026-09-16 - CVE-2026-81876 published to NVD
  • 2026-09-17 - Last updated in NVD database

Technical Details for CVE-2026-81876

Vulnerability Analysis

The vulnerability is an infinite loop condition [CWE-20] triggered during Smart Health Card JWT decompression. SHCParser.decodeJWT() calls SHCParser.inflate(), which drives java.util.zip.Inflater in a while (!inflater.finished()) loop. When the DEFLATE payload is empty or truncated, Inflater.inflate() returns zero bytes while Inflater.finished() remains false and Inflater.needsInput() returns true. The loop makes no progress but never exits.

The same zero-progress pattern exists in SHCParser.decompress(), and neither location checks Inflater.needsDictionary() as a termination condition. Because ResourceChecker.java can reach SHC parsing during file-format detection, the vulnerable path is reachable during routine validation rather than only when clients explicitly submit SHC content.

Root Cause

The root cause is missing loop-termination logic around Inflater.inflate(). The implementation assumes non-zero progress on each iteration and does not handle the documented case where the inflater returns zero bytes pending additional input or a preset dictionary. Empty or truncated raw-DEFLATE input satisfies exactly this condition.

Attack Vector

An unauthenticated remote attacker submits a validation request containing a crafted Smart Health Card JWT. The header declares zip: "DEF" while the payload segment contains an empty or truncated raw-DEFLATE stream. The receiving JVM worker thread enters the non-terminating inflate loop and consumes CPU indefinitely. Repeating the request in parallel exhausts the validation worker pool and denies service to legitimate clients.

java
     try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream(compressed.length)) {
       while (!inflater.finished()) {
         length = inflater.inflate(buffer);
-        outputStream.write(buffer, 0, length);
+        if (length > 0) {
+          outputStream.write(buffer, 0, length);
+        } else {
+          // Handle the 0 byte return condition
+          if (inflater.needsInput()) {
+            // Break out if no more input chunks are available
+            break;
+          }
+          if (inflater.needsDictionary()) {
+            // Break out if a preset dictionary is missing
+            break;
+          }
+        }
       }
       return outputStream.toString(StandardCharsets.UTF_8.name());
     }

Source: GitHub Commit edd5d8c. The patch adds needsInput() and needsDictionary() termination checks when Inflater.inflate() returns zero bytes.

Detection Methods for CVE-2026-81876

Indicators of Compromise

  • Validation requests containing JWT payloads with a header field zip: "DEF" and unusually short or empty compressed segments
  • FHIR worker threads observed in Inflater.inflate frames for extended periods via thread dumps
  • Sustained 100% CPU on one or more JVM threads correlated with /Validate, /$validate, or file-detection endpoints

Detection Strategies

  • Monitor validation endpoints for spikes in request duration, request timeouts, and thread-pool saturation
  • Periodically capture JVM thread dumps and alert on threads stuck in org.hl7.fhir.r5.elementmodel.SHCParser.inflate or decompress
  • Inspect HTTP request bodies for application/smart-health-card content or JWT structures whose header decodes to include "zip":"DEF"

Monitoring Recommendations

  • Enable per-request timeout and CPU-accounting metrics on FHIR validation services
  • Alert when the worker pool utilization exceeds a defined threshold for longer than the normal validation window
  • Correlate 5xx and gateway-timeout responses with source IPs submitting SHC payloads to identify probing activity

How to Mitigate CVE-2026-81876

Immediate Actions Required

  • Upgrade org.hl7.fhir.core to version 6.9.12 or later across all deployed HAPI FHIR services
  • Inventory applications that transitively depend on org.hl7.fhir.r5 and confirm the resolved version after upgrade
  • Enforce per-request wall-clock and CPU timeouts on validation worker threads to bound the impact of any similar future issue

Patch Information

The fix is delivered in org.hl7.fhir.core version 6.9.12 through pull request GitHub Pull Request #2493 and commits d804558 and edd5d8c. See the GitHub Security Advisory GHSA-gq9c-wmrm-5hvr for the full vendor advisory.

Workarounds

  • Reject or strip incoming Smart Health Card content at an API gateway or reverse proxy until the upgrade is complete
  • Configure request-size limits and reject JWT payloads whose compressed segment falls below a plausible minimum length
  • Isolate FHIR validation workloads into a dedicated worker pool so that thread exhaustion does not affect other endpoints
bash
# Maven dependency example - upgrade to the patched release
mvn versions:use-dep-version \
  -Dincludes=ca.uhn.hapi.fhir:org.hl7.fhir.r5 \
  -DdepVersion=6.9.12 \
  -DforceVersion=true

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.