HAPI FHIR: Incomplete fix for CVE-2026-45367: DSTU2 FHIRPathEngine.matches() missing RegexTimeout protection allows ReDoS
Date: 2026-06
Affected: maven/ca.uhn.hapi.fhir:org.hl7.fhir.validation.cli, maven/ca.uhn.hapi.fhir:org.hl7.fhir.validation, maven/ca.uhn.hapi.fhir:org.hl7.fhir.convertors
Attack vector: dos
Category: vulnerability-disclosure
Severity: High
CVE: CVE-2026-55470
CWE: CWE-1333
CVSS: 7.5 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

## Summary The fix for CVE-2026-45367 added `RegexTimeout` protection to the `matches()` function in DSTU2016MAY, DSTU3, R4, R4B, and R5, but the DSTU2 module was incompletely patched. In `org.hl7.fhir.dstu2`, `replaceMatches()` was updated while `matches()` at line 2462 still calls the raw `String.matches(sw)` without any timeout, allowing an unauthenticated attacker to trigger catastrophic regex backtracking and exhaust server CPU. ## Details ### Incomplete patch Within the same file (`org.hl7.fhir.dstu2/utils/FHIRPathEngine.java`), the two functions were patched inconsistently: **Line 2226 — replaceMatches() — PATCHED:** ```java result.add(new StringType( RegexTimeout.replaceAll( convertToString(focus.get(0)), regex, repl, regexTimeoutMillis))); ``` **Line 2462 — matches() — NOT PATCHED:** ```java result.add(new BooleanType( convertToString(focus.get(0)).matches(sw))); // ↑ raw String.matches() — no RegexTimeout, no complexity check ``` **DSTU3 line 2447 — matches() — PATCHED (for comparison):** ```java result.add(new BooleanType( RegexTimeout.matches(st, sw, regexTimeoutMillis))); ``` ### Module-by-module status | Module | `matches()` | `replaceMatches()` | |---|---|---| | **DSTU2** | ❌ raw `str.matches(sw)` | ✅ `RegexTimeout.replaceAll()` | | DSTU2016MAY | ✅ `RegexTimeout.matches()` | ✅ | | DSTU3 | ✅ `RegexTimeout.matches()` | ✅ | | R4 | ✅ `RegexTimeout.matches()` | ✅ | | R4B | ✅ `RegexTimeout.matches()` | ✅ | | R5 | ✅ `RegexTimeout.matches()`


Mitigations:

Architectural layers (MAESTRO):