Prevent XXE in the HL7 v2.x strict parser - #408
Open
pacmano1 wants to merge 1 commit into
Open
Conversation
The strict parser hands XML-encoded inbound messages to HAPI 2.3, whose XMLUtils.parse resolves external XML entities. On a channel with the strict parser and strict validation enabled, an unauthenticated message to the MLLP/TCP listener could trigger SSRF and local file disclosure. Override CustomDefaultXMLParser.parseStringIntoDocument -- the sole path to the vulnerable parse -- to reject DOCTYPE declarations, matching the disallow-doctype-decl hardening already used on the fromXML path. Legitimate HL7 v2.xml is schema-based and never carries a DOCTYPE, so no valid message is affected and the strict parser keeps accepting XML as before. Verified with a live MLLP reproduction (xxe-poc): the unpatched build fetched the attacker URL; the patched build rejects the message and never calls out. Signed-off-by: Finnegan's Owner <44065187+pacmano1@users.noreply.github.com>
pacmano1
requested review from
a team,
gibson9583,
jonbartels,
kayyagari,
kpalang,
mgaffigan,
ssrowe and
tonygermano
August 10, 2026 19:31
Test Results677 tests 677 ✅ 2m 22s ⏱️ Results for commit fefe2ea. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The HL7 v2.x strict parser hands XML-encoded inbound messages to the bundled HAPI 2.3, whose
XMLUtils.parseresolves external XML entities with no hardening. On a channel with Use Strict Parser + Validate in Strict Parser, an unauthenticated message to the MLLP/TCP listener could trigger SSRF (internal services, cloud metadata) and local file disclosure. Reported as oie-1; also independently reported by Samuel Paschuan.Fix
ER7Serializer.CustomDefaultXMLParser.parseStringIntoDocument— the sole path from OIE to the vulnerable parser — is overridden to rejectDOCTYPEdeclarations, matching thedisallow-doctype-declhardening already used on the siblingfromXMLpath (and ~20 other XML parse sites in the tree).This is a minimal, non-breaking change. The format the strict parser handles — the official HL7 v2.xml encoding (
urn:hl7-org:v2xml) — is defined by XML Schema, not DTDs, so a standards-conformant message does not use a DOCTYPE and is unaffected. (This is distinct from Mirth's own non-strict<HL7Message>format, which is a separate code path the override does not touch, and which is already DOCTYPE-hardened on thefromXMLside.) Any inbound message that does carry a DOCTYPE is now rejected rather than parsed — that is the intended hardening, since at the parser level a DOCTYPE-bearing message is indistinguishable from the attack. Existing channels need no changes: no new options, no migration, no configuration.How this was verified
hapi-base-2.3.jar:XMLUtilssets no doctype or external-entity restrictions.parseStringIntoDocumentis the only caller ofXMLUtils.parseacross all HAPI parser classes, and both of OIE's parser instances (serialization + deserialization) are the overriddenCustomDefaultXMLParser— it is the only HAPI XML parser instantiated in the server/donkey tree.xxe-pocchannel (MLLP :6661, strict + strict validation), sent the report's payload against an out-of-band HTTP catcher:DOCTYPE is disallowed— the message is rejected and the server never calls out.Tests
Unit tests fire the report's payload on the strict
toXMLpath and assert the parse is rejected with aDOCTYPE-disallowed root cause, alongside a benign v2.xml message that still round-trips (the hardening does not break valid XML).Honest caveat: the DOCTYPE-rejection unit test asserts the intended behavior but does not by itself discriminate patched from unpatched, because the test-JVM's default XML parser rejects a DOCTYPE regardless — the engine runtime is where HAPI resolves a different, vulnerable parser. The discriminating before/after evidence is the live MLLP reproduction above.
Follow-ups (separate)
hapi-structures2.3 → 2.6.0 bump is tracked by Renovate in the Dependency Dashboard (Dependency Dashboard #386); the vendoredhapi-basejar needs replacing alongside it. This override should stay even after the upgrade: HAPI's 2.4+ fix leavesdisallow-doctype-decl=false(permits a DOCTYPE, only disables entity resolution), so this refusal is the stronger posture.XMLBatchAdaptorparses inbound content with an unhardenedXPathFactory) was found during this work and will be filed and fixed separately.Credits
Thanks to Samuel Paschuan for reporting the issue, and to Michael Gaffigan (@mgaffigan) and Tony Germano for the design discussion.