Safeguard
Supply Chain Security•

HAPI FHIR CVE-2026-113874: Cross-Tenant Partition Override, No Fix Yet

CISA published four HAPI FHIR CVEs on 22 Oct 2026; three have no fix. Block the cross-tenant partition override now with an interceptor and gateway rule.

Safeguard Security Team
36 min read

On 22 October 2026 CISA published advisory VA-26-294-01 with four CVEs in HAPI FHIR, the open source Java FHIR server. The worst, CVE-2026-113874 (CVSS 8.1), lets a caller authorized for one tenant read or create data in another tenant's partition. Three of the four have no fix. Mitigate now with a partition entitlement interceptor and gateway rules.

This is a vulnerability disclosure, not a breach. No exploitation is reported. None of the four CVEs is in the CISA Known Exploited Vulnerabilities (KEV) catalog as of the 23 October release, and CISA's decision notes record exploitation status as "none." The researcher has withheld his proof of concept code until released versions fix the remaining findings.

What makes this disclosure unusual is the fix status. For three of the four CVEs, CISA's advisory says "No fix available." The next major release, 9.0.0, is scheduled for 19 November 2026 and, according to the researcher, is a breaking upgrade with no 8.x backport. Until then the mitigations are in your hands, and they are configuration and interceptor changes a Java team can ship this week.

What happened

HAPI FHIR is the most widely used open source implementation of HL7 FHIR in Java. It ships as a set of Maven libraries under the ca.uhn.hapi.fhir group, as a reference JPA server, and as a Docker image. It sits underneath many commercial and public sector FHIR products. CISA lists the vendor as SmileCDR, the company that maintains the project.

An independent researcher, Abhinav Agarwal, reported four findings against HAPI FHIR 8.10.0 (commit 96ac50f89455). The case was coordinated through CERT/CC as VU#394579. On 22 October CISA, acting as CVE Numbering Authority under its cisa-cg short name, published a CSAF advisory and the four CVE records. A few hours later the researcher posted a technical summary to the oss-security mailing list and published a longer write-up on his own site.

The four findings, in CISA's titles:

CVECISA titleCWECVSS 3.1Fix status per CISA
CVE-2026-113874trusted tenant partition overrideCWE-863 Incorrect Authorization8.1 HighNo fix available
CVE-2026-113873improper data decompressionCWE-409 Improper Handling of Highly Compressed Data7.5 HighNo fix available
CVE-2026-113876unauthorized readCWE-863 Incorrect Authorization4.3 Medium"Fixed around September 2026"
CVE-2026-113875unauthorized read via subscriptionCWE-862 Missing Authorization3.1 LowNo fix available

CISA's risk summary is short. In the worst case, it says, "a user could read or write content in a tenant partition that they should not have access to, or an unauthenticated user could trigger a denial-of-service." Its recommended practice is to update to the most recent available version, but as the rest of this post shows, the most recent release does not contain any of the fixes.

Timeline

All times are UTC unless stated. Each row names the source we read.

Date and timeEventSource
21 May 2026, 19:12HAPI FHIR v8.10.0 released (the version the researcher tested)GitHub releases
11 to 12 Jul 2026Findings confirmed against commit 96ac50f89455, each with a passing testResearcher write-up
12 Jul 2026, 11:24Coordination case VU#394579 openedoss-security post
22 Jul 2026, 21:11v8.10.1 releasedGitHub releases
13 Aug 2026, 21:04Upstream issue #8253 opened: AuthorizationInterceptor does not read authorize write response bodies (PATCH, conditional create). The researcher describes this as an independent upstream report of the conditional create pathGitHub issue #8253
19 Aug 2026, 19:20PR #8254 "Read authorize patch and conditional create responses" merged to master as commit 063b073e8c1GitHub PR #8254
1 Sep 2026, 16:31v8.12.0 releasedGitHub releases
15 Sep 2026, 06:29v8.12.1 released, the newest version on Maven CentralGitHub releases, Maven Central
22 Sep 2026, 19:22PR #8404 merged to master: STORAGE_PARTITION_SELECTED now fires for partition selecting requests without a resource typeGitHub PR #8404
25 Sep 2026, 21:05v8.8.2 released (maintenance line)GitHub releases
6 Oct 2026, 16:13 to 17:12CISA records its SSVC decisions for the four CVEsCISA CSAF VA-26-294-01
20 Oct 2026, 20:11 to 20:12CVE IDs reservedCVE records
22 Oct 2026, 17:14:18CISA publishes CSAF advisory VA-26-294-01, version 1.0.0, TLP WHITECISA CSAF
22 Oct 2026, 17:57:52 to 18:00:15CVE-2026-113873, 113874, 113875 and 113876 records publishedCVE records
22 Oct 2026, 15:42 PDT (22:42 UTC)Researcher posts the disclosure to oss-securityOpenwall archive
23 Oct 2026, 19:30KEV catalog version 2026.10.23 released; none of the four CVEs listedCISA KEV feed
19 Nov 2026 (scheduled)HAPI FHIR 9.0.0, which the researcher says carries the conditional create change but is a breaking upgradeResearcher write-up

Who is affected

The CVE records list every version of HAPI FHIR as affected for three of the CVEs. In CVE terms, the affected range runs from version 0 with no upper bound, and the default status is "unknown." For CVE-2026-113876 the affected range is "less than September 2026," which is a date, not a version number. We return to that oddity below.

The researcher's own scope is more precise. He tested 8.10.0. Reading the source on 22 October, he found all four code paths present in v8.8.2, v8.10.1 and v8.12.1. On master, three paths are unchanged and the conditional create response body is suppressed. The partition extension handler behind CVE-2026-113874 first shipped in v8.2.0.

Being on an affected version is necessary but not sufficient. Each bug needs a particular configuration. This table, built from the researcher's prerequisites list and module names, is the one to work through with your platform team:

CVEModuleExposed only ifDefault state
CVE-2026-113874hapi-fhir-storage (JPA)Partitioning is on, tenant routing uses RequestHeaderPartitionInterceptor fed by a trusted header, callers can POST transaction or batch Bundles, and no STORAGE_PARTITION_SELECTED entitlement hook is registeredHAPI ships no entitlement hook
CVE-2026-113873hapi-fhir-serverInbound decompression is on and some reachable operation reads a request bodyDecompression is on by default
CVE-2026-113876hapi-fhir-server, hapi-fhir-storageAuthorizationInterceptor grants CREATE without READ on a resource typeDefault response is the full representation
CVE-2026-113875hapi-fhir-jpaserver-subscriptionREST hook subscriptions are enabled and non administrators can create Subscription resourcesREST hook subscriptions are off by default

Who that means in practice

Single tenant servers have no tenant boundary to cross, so CVE-2026-113874 does not apply, though the other three may. The override matters most where one HAPI JPA database holds several organisations' data and a gateway picks the partition: payer to payer exchange, health information exchanges, multi-tenant SaaS EHR and shared internal platforms. The gzip bug matters for anything reachable from an untrusted network.

Downstream products

The researcher counted, as of 22 October, 2,254 GitHub repositories declaring hapi-fhir-base and about 25.3 million Docker pulls of hapiproject/hapi since December 2019. He notes these count different things and include forks, so treat them as scale, not a census.

He also reports that Smile CDR's changelog maps Smile CDR 2026.05.R01 to HAPI FHIR 8.10.0, 2026.05.R02 to 8.10.1, 2026.08.R02 to 8.12.1 and 2026.02.R03 to 8.8.2. He did not test Smile CDR, which has its own modules, so the mapping alone does not show any finding is reachable there. We could not load the changelog to confirm it. Do not assume a product built on HAPI is affected, or that it is safe. Ask your supplier for a written statement on each CVE and the exact build that addresses it.

How the four issues work

This section explains each bug in plain terms so you can judge exposure. It names the vulnerable methods, which help when reading your own code and logs, and leaves out request bodies and test code.

CVE-2026-113874: the partition header gets overwritten

In a typical multi-tenant setup, a gateway authenticates the caller, removes any partition header the caller sent, and writes the caller's tenant into X-Request-Partition-IDs. HAPI's RequestHeaderPartitionInterceptor reads that trusted header and picks the partition.

FHIR also lets a client send many operations in one transaction or batch Bundle, and HAPI processes each entry as a sub-request. Since v8.2.0, HAPI has honoured a per-entry request-partition-ids extension. When an entry carries it, BaseTransactionProcessor.setRequestPartitionHeaderIfEntryHasTheExtension() copies its value into the sub-request's partition header with no authorization check, according to the researcher. The value the gateway set is replaced by one that came from the request body.

The partition then reaches the STORAGE_PARTITION_SELECTED pointcut, which HAPI's documentation describes as the place where an interceptor can "make decisions about whether the request should be allowed to proceed." HAPI does not ship such an interceptor. CISA puts it plainly: HAPI "does not enforce storage partition entitlement by default."

In the researcher's tests, one batch request read Patient records from three partitions, and a transaction created a Patient in a foreign partition. He did not test changing or deleting existing foreign records. A control test with an entitlement hook blocked the override. The gateway did its job; the server trusted something the gateway never saw.

CVE-2026-113873: decompression before authorization

HAPI's RestfulServer decompresses inbound request bodies by default; the javadoc for setUncompressIncomingContents says the default is true. With Content-Encoding: gzip, the body is inflated into memory with no limit on size or ratio.

This happens while HAPI builds method parameters, before AuthorizationInterceptor runs, so no authorization is needed (PR:N). In the researcher's test, a 65,250 byte body expanded to 64 MiB, about 1,028 to 1, and in a JVM with a 64 MiB heap a body of about 255 KB triggered OutOfMemoryError. He called the routine directly and did not measure an outage of a running server. CISA's SSVC notes mark this one as automatable.

CVE-2026-113876: conditional create shows a record you cannot read

FHIR conditional create, via the If-None-Exist header, means "create this, unless a match exists." On a match HAPI creates nothing and, by default, returns the existing record in full. AuthorizationInterceptor treats CREATE as inbound, and its outgoing check returns early for inbound operations. So a caller with CREATE but no READ can receive a full stored record, provided it already knows a search value matching exactly one. The researcher did not demonstrate enumeration.

Upstream PR #8254 now suppresses the body when a CREATE creates nothing. The researcher notes it does not add a read check: the matched id still returns in the Location header, and 200 versus 201 still reveals whether a match existed.

CVE-2026-113875: subscriptions deliver more than the creator can read

REST hook subscriptions, off by default, push matching resources to a URL the subscriber chooses. The researcher found that neither creation nor delivery applies the creator's read rules; delivery reloads the resource as SystemRequestDetails, a full privilege internal identity. In his test, an Observation from another patient's compartment, same partition, reached the subscriber's endpoint though the subscriber could not read it directly. This is a read scope bypass, not a cross-tenant leak.

Technical details

Every value below comes from the CISA CSAF document, the CVE records, the researcher's oss-security post and write-up, the HAPI FHIR GitHub repository or the HAPI FHIR documentation. There are no file hashes, IP addresses or domains to list: this is a vulnerability disclosure with no reported exploitation, and no source publishes indicators of compromise.

Advisory identifiers

ItemValueSource
CISA advisoryVA-26-294-01, CSAF 2.0, category csaf_vex, version 1.0.0, status finalCISA CSAF
Initial and current release2026-10-22T17:14:18ZCISA CSAF
GeneratorVINCE-NT 1.15.0+build.129CISA CSAF
Coordination caseCERT/CC VU#394579, opened 2026-07-12 11:24 UTCoss-security post
CNAcisa-cgCVE records
Vendor as listedSmileCDR, product HAPI FHIRCISA CSAF, CVE records
Sectors and deploymentInformation Technology; Worldwide; headquarters United StatesCISA CSAF
CreditAbhinav AgarwalCVE records

The researcher notes that VA-26-294-01 is CISA's machine readable CSAF record and that, as of his post, a traditional human readable CISA advisory had not been published.

Per-CVE detail

CVEVectorPublished (UTC)Reserved (UTC)SSVC decision string
CVE-2026-113874CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N2026-10-22 17:58:562026-10-20 20:11:55SSVCv2/E:N/A:N/T:P/2026-10-06T16:14:15Z/
CVE-2026-113873CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H2026-10-22 17:57:522026-10-20 20:11:47SSVCv2/E:N/A:Y/T:P/2026-10-06T16:13:10Z/
CVE-2026-113876CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N2026-10-22 18:00:152026-10-20 20:12:13SSVCv2/E:N/A:N/T:P/2026-10-06T17:12:44Z/
CVE-2026-113875CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N2026-10-22 18:00:012026-10-20 20:12:03SSVCv2/E:N/A:N/T:P/2026-10-06T16:15:54Z/

In CISA's SSVC notation, E:N means exploitation status none, A:Y or A:N means automatable yes or no, and T:P means partial technical impact.

Affected and fixed versions

CVECVE record affected rangeResearcher's source check, 22 OctFixed in a release?
CVE-2026-113874version 0, less than * (all)Present in v8.8.2, v8.10.1, v8.12.1 and master; handler unchanged; introduced in v8.2.0 (commit 85abdc23007)No
CVE-2026-113873version 0, less than * (all)Present; ServletRequestDetails.java byte identical across every ref inspectedNo
CVE-2026-113875version 0, less than * (all)Present; no commits to the relevant classesNo
CVE-2026-113876less than September 2026; September 2026 unaffectedBody suppression in 063b073e8c1 on master and the rel_9_0 branch onlyNo released tag as of 22 Oct; scheduled for 9.0.0

Released versions on Maven Central for ca.uhn.hapi.fhir:hapi-fhir-base, newest first, with GitHub release dates: 8.12.1 (15 Sep), 8.12.0 (1 Sep), 8.10.1 (22 Jul), 8.10.0 (21 May), 8.8.2 (25 Sep, maintenance line), 8.8.1, 8.8.0, 8.6.8. Per the researcher, none of these contains a fix for any of the four CVEs.

Vulnerable code locations

These method names come from the researcher's write-up and oss-security post. Line numbers there refer to commit 96ac50f89455.

CVEClass and methodRole
CVE-2026-113874BaseTransactionProcessor.setRequestPartitionHeaderIfEntryHasTheExtension()Copies the entry extension value over the sub-request partition header
CVE-2026-113874ServletSubRequestDetails.setHeaders()Replaces the sub-request headers (remove all, then put all)
CVE-2026-113874BaseRequestPartitionHelperSvc.validateAndNormalizePartition()Broadcasts STORAGE_PARTITION_SELECTED, where an entitlement hook can block
CVE-2026-113873ServletRequestDetails.getByteStreamRequestContents()Inflates gzip bodies with no cap
CVE-2026-113873RestfulServer field myUncompressIncomingContentsDefaults to true
CVE-2026-113876AuthorizationInterceptor.hookPreShow() and checkOutgoingResourceAndFailIfDeny()Skips the outgoing check for inbound operations such as CREATE
CVE-2026-113876BaseHapiFhirResourceDao.doCreateForPostOrPut()Returns the stored entity on a single match
CVE-2026-113875SubscriptionValidatingInterceptor.validateSubmittedSubscription()Does not apply the creator's read policy at creation
CVE-2026-113875SubscriptionDeliveringRestHookListener.getResource()Reloads the resource as SystemRequestDetails at delivery

Key strings to search for

StringWhere it matters
http://hapifhir.io/fhir/ns/StructureDefinition/request-partition-idsThe Bundle entry extension URL behind CVE-2026-113874. Search gateway logs, stored request bodies and your own client code for it
X-Request-Partition-IDsThe trusted header your gateway sets for RequestHeaderPartitionInterceptor
RequestHeaderPartitionInterceptorTells you a server uses header based tenant routing
STORAGE_PARTITION_SELECTEDIf no class in your code hooks this pointcut, you have no partition entitlement check
setUncompressIncomingContentsIf your code never calls this with false, inbound gzip decompression is on
If-None-ExistConditional create header for CVE-2026-113876
rest-hookSubscription channel type for CVE-2026-113875

A related upstream change to know about

Upstream PR #8404, merged to master on 22 September, says that before it, STORAGE_PARTITION_SELECTED "was only fired when the request carried a resource type." Partition selecting requests without one, such as system level _history, result paging, transactions and server level operations, skipped the hook. The PR description says this let a client scoped to one partition read another partition's data. The researcher says the change is unreleased, adds no entitlement policy, and leaves the extension handler unchanged.

That matters for your mitigation. In the researcher's tests, the entitlement hook blocked the override on typed entries inside a Bundle. But on released versions, a hook alone does not cover untyped, partition selecting requests. Pair it with gateway rules, described below.

What to do now

Work through these steps in order. The first two tell you whether you are exposed at all. Steps 3 to 6 are the four mitigations. Step 7 is how you verify.

1. Find every HAPI FHIR in your estate

HAPI often hides inside other things: a Spring Boot fat jar, a vendor appliance, an integration engine, a test harness that ended up in production.

For Maven projects:

mvn -q dependency:tree -Dincludes=ca.uhn.hapi.fhir

For Gradle projects:

./gradlew dependencies --configuration runtimeClasspath | grep 'ca.uhn.hapi.fhir'

For built artifacts, including Spring Boot jars that keep dependencies under BOOT-INF/lib:

unzip -l app.jar | grep -E 'hapi-fhir-(base|server|storage|jpaserver)'
find / -name 'hapi-fhir-*.jar' 2>/dev/null

For container images and SBOM files, scan with the Safeguard CLI, which writes JSON results under ./output:

safeguard scan --image registry.example.com/fhir-server:prod
safeguard scan --sbom fhir-server.cdx.json
safeguard scan --dir .

Record, for each hit, the HAPI version, which modules are present (hapi-fhir-jpaserver-base and hapi-fhir-storage matter for the partition bug, hapi-fhir-jpaserver-subscription for subscriptions), and who owns the service.

For products you buy rather than build, ask the supplier three questions in writing: which HAPI FHIR version and modules the product contains, whether each of the four CVEs is reachable in the product's configuration, and which exact build fixes or mitigates each one.

2. Check whether the risky configuration is on

Search your server code for the strings in the table above:

grep -rn --include=*.java -E 'RequestHeaderPartitionInterceptor|RequestTenantPartitionInterceptor|STORAGE_PARTITION_SELECTED|setUncompressIncomingContents|AuthorizationInterceptor|SubscriptionSettings|rest-hook' src/

Then answer, for each server:

  1. Does a gateway header decide the partition? If yes, CVE-2026-113874 is the priority.
  2. Can tenant callers POST transaction or batch Bundles to the base endpoint? If the gateway allows POST /fhir, assume yes.
  3. Does any class hook STORAGE_PARTITION_SELECTED? If not, there is no entitlement check.
  4. Does the code call setUncompressIncomingContents(false)? If not, inbound gzip is on.
  5. Do any rules grant CREATE on a type without READ?
  6. Are REST hook subscriptions enabled, and who can create one?

3. CVE-2026-113874: add a partition entitlement check and strip the extension

There are two controls. Use both.

Control A, in HAPI: register a STORAGE_PARTITION_SELECTED interceptor. The researcher tested this control and it blocked the override. The hook receives the selected RequestPartitionId and the RequestDetails. Its job is to compare the final partition with the partitions the authenticated caller is entitled to, and to refuse anything else.

The critical design point: do not derive the caller's entitlement from X-Request-Partition-IDs inside this hook. That header is exactly the value the transaction processor overwrites on the sub-request. Derive entitlement from the authenticated identity instead, for example a validated token claim, or a value you stored on the parent request in an earlier hook before Bundle processing began.

A minimal sketch, to adapt and test against the javadoc for your HAPI version:

@Interceptor
public class PartitionEntitlementInterceptor {

  private final TenantEntitlements entitlements; // your own lookup, keyed by authenticated principal

  public PartitionEntitlementInterceptor(TenantEntitlements entitlements) {
    this.entitlements = entitlements;
  }

  @Hook(Pointcut.STORAGE_PARTITION_SELECTED)
  public void checkPartition(RequestPartitionId selected, RequestDetails request) {
    if (request == null) {
      return; // internal system work; review whether this is acceptable in your deployment
    }
    if (selected.isAllPartitions()) {
      throw new ForbiddenOperationException("All-partition access is not permitted");
    }
    Set<Integer> allowed = entitlements.allowedPartitionIdsFor(request); // from the token, not the header
    for (Integer id : selected.getPartitionIds()) {
      if (!allowed.contains(id)) {
        throw new ForbiddenOperationException("Partition not permitted for this caller");
      }
    }
  }
}

Points to get right:

  1. Decide how to treat the default partition, stored as a null PARTITION_ID, and partition names if you use them.
  2. Register the interceptor on the same registry as your partition interceptors.
  3. Test each case: own partition allowed, foreign partition refused, default partition per your rule, a batch with mixed entries refused.
  4. Remember PR #8404: on released versions the hook does not fire for partition selecting requests without a resource type. Control B covers that gap.

Control B, at the gateway: refuse the extension and limit untyped operations. Your gateway already strips a caller supplied X-Request-Partition-IDs header. Treat the per-entry extension the same way. The simplest rule is to reject, with HTTP 400, any request body that contains the extension URL string. Rejecting is clearer than silently removing it, and you can log the event. If no legitimate client of yours uses per-entry partition routing, nothing should break.

For gateways that can inspect JSON, the check is whether any Bundle.entry.request.extension.url equals the extension URL. A blunt string match on the raw body also works and catches XML Bundles:

# Example logic for a gateway plugin or a quick log review
grep -l 'hapifhir.io/fhir/ns/StructureDefinition/request-partition-ids' /var/log/fhir-gateway/bodies/*

Then review which untyped endpoints tenant callers can reach: system level _history, paging links, server level operations and the base endpoint for transactions. If tenants do not need them, block them at the gateway for tenant scoped credentials.

4. CVE-2026-113873: switch off inbound decompression or cap it

If your clients do not send compressed request bodies, turn decompression off in HAPI:

restfulServer.setUncompressIncomingContents(false);

The javadoc says this setting should normally stay true unless something else handles decompression, so confirm first that no client relies on it. Check your access logs for Content-Encoding on inbound requests before you change it.

You can also refuse compressed bodies at the reverse proxy. For example, in nginx:

if ($http_content_encoding ~* "gzip|deflate") {
    return 415;
}

If some clients do need compression, enforce a limit on the decompressed size before the body reaches HAPI, in a servlet filter or a proxy that decompresses and counts. The researcher is explicit that a cap on the compressed size alone, such as nginx client_max_body_size, is not enough, because a small compressed body can expand by three orders of magnitude.

As defence in depth, alert on JVM heap pressure and OutOfMemoryError in the FHIR server, and make sure the orchestrator restarts a crashed pod.

5. CVE-2026-113876: audit CREATE without READ

List every authorization rule that allows CREATE on a resource type, and check whether the same caller can READ that type. In a typical AuthorizationInterceptor subclass, that means reviewing buildRuleList for allow().create() rules that have no matching allow().read() rule.

grep -rn --include=*.java -E 'allow\(\)\.create\(\)|allow\(\)\.read\(\)|allow\(\)\.write\(\)' src/

Where CREATE without READ is a real business need, for example an intake system that files new records but must not browse them, suppress the response body for conditional creates that matched an existing record on the server side. The researcher notes that the client's Prefer: return=minimal header does not help, because the caller chooses it. He also notes that a ConsentInterceptor can cover this path, but only if its policy is written to do so.

CISA says this one was "Fixed around September 2026," without naming a release. The researcher found the fix only on master and the 9.0 branch. Until you can run a release that contains commit 063b073e8c1, treat CVE-2026-113876 as unfixed in your environment.

6. CVE-2026-113875: lock down subscription creation

Restrict creating and updating Subscription resources to administrators. Then audit what already exists, with an administrator token:

curl -s -H "Authorization: Bearer $ADMIN_TOKEN" \
  "https://fhir.example.com/fhir/Subscription?status=active&type=rest-hook&_elements=criteria,channel,status" \
  | jq '.entry[]?.resource | {id, criteria, endpoint: .channel.endpoint}'

Look for broad criteria (for example a whole resource type with no patient or organisation filter) and endpoints outside domains you control. The researcher notes that egress blocking stops delivery to a blocked destination but does not add a read check, so it is a partial control. If you do not use REST hook subscriptions at all, keep them disabled.

7. Verify

  1. Keep the entitlement interceptor tests in CI.
  2. On a test instance with synthetic data, confirm the gateway rejects the extension URL and the interceptor refuses a foreign partition when the gateway is bypassed.
  3. Confirm compressed requests are refused or capped.
  4. Record the HAPI version and these controls in the service's security notes, so the 9.0.0 upgrade does not silently remove them.

How to look for signs of misuse

There is no reported exploitation, so there are no published indicators to hunt for. You can still check your own data for the patterns these bugs would leave.

  1. Extension URL in logs. If request bodies are logged, search for the request-partition-ids URL from clients that should never use it.
  2. Batch volume per tenant. A sudden rise in read heavy transaction or batch POSTs from one tenant's credentials.
  3. Records in unexpected partitions. HAPI stores a PARTITION_ID per resource; compare it with the tenant credential your audit trail says created the record.
  4. Conditional creates that matched. Status 200 responses to POSTs carrying If-None-Exist from callers lacking READ on that type.
  5. Subscriptions and memory. New Subscriptions with broad criteria or unfamiliar endpoints, and OutOfMemoryError or pod restarts that line up with compressed requests.

If you find something, treat it as a potential health data incident, including your reporting obligations.

What changed since first reports

The disclosure is two days old as of this review. Since the CISA publication on 22 October:

  1. The researcher's oss-security post and write-up added module level prerequisites, method names, the v8.2.0 origin of the extension handler and the 9.0.0 schedule, none of which appear in the CSAF record.
  2. KEV catalog version 2026.10.23, released on 23 October, does not list any of the four CVEs.
  3. We found no vendor statement or vendor advisory from SmileCDR or the HAPI FHIR project about the four CVEs. Check the HAPI FHIR GitHub repository and release notes for updates.

Open questions

  1. What does "Fixed around September 2026" mean for CVE-2026-113876? CISA's record names a date, not a version. The researcher found the response body change only on master and the 9.0 branch, and in no release tag. Neither source explains the gap. The researcher advises operators to get an exact fixed build statement from their supplier.
  2. When will the other three be fixed? No fix date exists for CVE-2026-113873, CVE-2026-113874 or CVE-2026-113875. The PR #8404 change is related but does not fix the extension handler.
  3. Will 8.x get a backport? The researcher says 9.0.0 is a breaking Spring Boot 4, Jackson 3 and Hibernate 7 upgrade with no 8.x backport. We did not find a project statement confirming or contradicting that.
  4. Which downstream products are reachable? Unknown. Commercial distributions and products that embed HAPI may or may not expose these paths, depending on their modules and configuration.

What would have helped

None of these bugs is exotic. Each is a trust decision made in one layer and undone, or never made, in another. These practices help with this disclosure and the next one like it.

Practices any team can use

  1. Enforce tenancy where the partition is finally chosen, not only at the edge. A gateway header is a routing decision; an entitlement check at storage is a security decision. It should not read anything the caller can influence.
  2. Treat every body field that changes routing as untrusted. Extensions that select a tenant or partition deserve the same stripping as the partition header.
  3. Bound everything that inflates. Decompression, Bundle size and entry counts need limits before authorization work starts.
  4. Write negative tests for authorization. For each role, test what it must not do: read a foreign partition, read through a write response, receive subscription data it cannot read.
  5. Keep a living inventory of embedded libraries. When the answer is "all versions, no fix," the first question is where it runs. An SBOM per service and image answers that in minutes. See using SBOMs to find affected products fast.
  6. Ask suppliers about components, not just products. Contracts that require component disclosure and fix statements make this week's questions faster to answer.
  7. Plan the major upgrade now. If 9.0.0 is the first release with any fix, teams already testing against Spring Boot 4, Jackson 3 and Hibernate 7 will move fastest.

We have written before about why FHIR on its own does not provide the controls a production deployment needs: see FHIR is not a security protocol and FHIR security is not built in. Earlier HAPI FHIR issues we covered include the Saxon XXE in CVE-2026-55471, the credential prefix match in CVE-2026-34359 and the validator loading issue in CVE-2026-34361.

Zero-Day Discovery and Gold

Safeguard's Zero-Day Discovery looks for previously unknown flaws before a CVE exists, in an agentic mode and a deterministic scanner mode, across seven package ecosystems, and issues findings as SGZ advisories before they reach public CVE databases. The point is what such tools are for: catching authorization flaws in widely embedded libraries early.

Gold Open Source (gold.safeguard.sh, free, no login) shows CVSS, EPSS, KEV status, affected and fixed versions and a recommended safe version, with a free read API and a CI gate GitHub Action. Gold Registry (registry.safeguard.sh, paid) offers hardened drop in components and images held to zero exploitable critical or high CVEs, SLSA L3 or higher and Sigstore signed. We make no claim that Gold holds a patched HAPI FHIR build for these CVEs. With no upstream fix, the habit that matters is knowing which builds carry the library and rebuilding from a patched, signed source as soon as one exists.

Where Safeguard fits

Here is what Safeguard does and does not do for this disclosure.

  1. Finding the library. Safeguard's dependency scanning reads Maven and Gradle projects, container images and SBOM files and builds a full transitive inventory, so the scan commands in step 1 find ca.uhn.hapi.fhir artifacts even when something else pulled them in. The platform shows which projects contain a given component and version.
  2. Matching the CVEs. Vulnerability matching will flag affected HAPI versions as the records propagate. Because three records say "all versions," that tells you where the library is, not whether you are exposed. Exposure depends on partitioning, gateway design and interceptors, which a dependency scan cannot see.
  3. Policies and gates. A policy can flag services carrying HAPI FHIR until the owning team records that the mitigations are in place.
  4. Writing and testing the mitigation. The Safeguard CLI's assistant can edit code and run commands with your approval: add the STORAGE_PARTITION_SELECTED interceptor, write the negative tests, run mvn verify. The /permissions modes (Ask, Accept edits, Plan, Auto, Strict) set how much it does without asking, and safeguard exec runs the same kind of task in CI.
  5. The upgrade later. When a fixed release ships, autonomous remediation can open tested fix pull requests. It ships switched off.

Where Safeguard does not help: it cannot decide your tenant entitlement model, configure your API gateway, or see inside a vendor's hosted FHIR service. For products you buy, the fix must come from the supplier. Nothing here would have prevented these bugs; the value is finding affected services quickly and shipping controls with less friction.

Common mistakes and troubleshooting

  1. Reading entitlement from the header inside the hook. The header is what the transaction processor overwrites. Use the authenticated identity.
  2. Testing only plain reads. Many teams test GET Patient/123 across tenants and stop. The override arrives inside a Bundle, so tests must POST transaction and batch Bundles too.
  3. Relying on the hook alone on released versions. Until PR #8404 ships, the hook is skipped for partition selecting requests without a resource type. Block those paths for tenant credentials at the gateway.
  4. Capping only the compressed body size. A 65 KB body can become 64 MiB.
  5. Turning off decompression without checking clients. Some integration engines compress large uploads. Check access logs first, or you will break a feed.
  6. Forgetting the default partition. If the hook refuses it outright, shared terminology lookups may break. Decide explicitly which types and operations may use it.
  7. Losing the controls during the 9.0.0 upgrade. Major upgrades are when custom interceptors get dropped. Keep the negative tests in CI so the upgrade fails loudly.

FAQ

What is CVE-2026-113874?

It is an incorrect authorization flaw in HAPI FHIR, scored 8.1 by CISA. A caller authorized for one tenant can add a request-partition-ids extension to an entry in a transaction or batch Bundle, and that value replaces the partition the gateway set. The server then reads from or writes to the other tenant's partition, unless a STORAGE_PARTITION_SELECTED entitlement hook blocks it.

Is there a patch for the HAPI FHIR vulnerabilities?

Not for three of them. CISA lists "No fix available" for CVE-2026-113873, CVE-2026-113874 and CVE-2026-113875. For CVE-2026-113876, CISA says "Fixed around September 2026," but the researcher found the change only on master and the 9.0 branch, not in any released version as of 22 October.

Is anyone exploiting these bugs?

No exploitation has been reported. CISA's SSVC notes record exploitation as none, and none of the four CVEs is in the KEV catalog as of 23 October. The researcher has withheld his proof of concept code until fixes ship.

Which HAPI FHIR versions are affected?

The CVE records list all versions. The researcher tested 8.10.0 and found the code paths in v8.8.2, v8.10.1 and v8.12.1, the newest release. The partition extension handler behind CVE-2026-113874 first shipped in v8.2.0, so versions before 8.2.0 do not have that specific code path, though they may have the other three issues.

Am I affected if I do not use partitioning?

Not by CVE-2026-113874, which needs partitioning and header based tenant routing. You may still be affected by the gzip bug, which applies to default configurations, and by the conditional create and subscription bugs if your authorization rules and subscription settings match their prerequisites.

When will HAPI FHIR 9.0.0 ship, and will it fix everything?

The researcher says 9.0.0 is scheduled for 19 November 2026 and is a breaking upgrade to Spring Boot 4, Jackson 3 and Hibernate 7 with no 8.x backport. Based on his source review, the 9.0 branch contains the conditional create change. He found the other three paths unchanged as of 22 October. Check the release notes when it ships.

Does this affect Smile CDR?

Unknown. The researcher reports that Smile CDR releases are based on specific HAPI versions, but he did not test Smile CDR, which has its own modules. CISA lists SmileCDR as the vendor for HAPI FHIR, the open source project. Ask your account contact for a statement on each CVE.

Does Prefer: return=minimal stop the conditional create leak?

No. The client chooses that header, so a caller who wants the body leaves it out. Fix the authorization rules or suppress the body on the server side.

Fix it without waiting for upstream

This disclosure is a clear case for what follows: three of the four HAPI FHIR CVEs have no upstream fix, and the controls that work today are ones your own team ships.

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.

3. Gold Registry: start from components that are already fixed

registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingThe Gold scan GitHub Action in CI, plus Safeguard policies and gates
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch (early access)
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would have helped

None of these demos shows HAPI FHIR. Each shows a real flow that maps onto the work this disclosure asks of a Java team running FHIR.

The first demo is a real Safeguard CLI session. It installs the CLI, opens the interactive terminal and asks it to fix a lodash CVE: the assistant reads the finding and advisory, asks before each command, edits package.json to lodash 4.17.21, runs npm install and npm test with approval, and pushes nothing. For HAPI FHIR you would ask the same assistant to add a STORAGE_PARTITION_SELECTED entitlement interceptor and the negative Bundle tests to your server module, then approve mvn verify before anything runs.

Click through it at your own pace, or open it full screen.

The second demo sets up the Safeguard runner on your own machine, approves it with its device code and then scans from the terminal. That is the step that answers "which of our services and images carry ca.uhn.hapi.fhir jars, and which version" across the repositories you already have checked out, including the fat jars where HAPI hides.

Click through it at your own pace, or open it full screen.

The third demo is a real desktop app session. The CLI session shows in the conversation list, you ask for work on your computer, pick the folder, and Approve or Deny each command and file edit; it ends with the upgrade done and tests passing. Here you would point it at the FHIR server repository, ask it to call setUncompressIncomingContents(false) where your clients never compress, and approve the build and test commands one at a time.

Click through it at your own pace, or open it full screen.

To try it on your own code, download Safeguard and follow the CLI documentation.

Quick check

Your multi-tenant HAPI FHIR 8.12.1 server uses RequestHeaderPartitionInterceptor behind a gateway that strips the partition header. Are you protected from CVE-2026-113874?

No. The override comes from a Bundle entry extension, not the header, and 8.12.1 contains the vulnerable handler. Register a STORAGE_PARTITION_SELECTED entitlement interceptor that checks the authenticated caller, and reject the request-partition-ids extension URL at the gateway.

Which of the four HAPI FHIR CVEs can be triggered without authentication?

CVE-2026-113873, the gzip decompression bug. HAPI inflates the request body before AuthorizationInterceptor runs, which is why its CVSS vector says PR:N. Turn off inbound decompression or cap the decompressed size ahead of HAPI.

Sources

Last reviewed: 24 October 2026. This is a developing story; check the linked advisories for the latest status.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.