GHSA-442q-2j6p-642g: datamodel-code-generator vulnerable to arbitrary local file read via XSD `schemaLocation` (`xs:include`/`xs:import`) path traversal, with no remote-ref gate
Summary
When generating models from an XML Schema (--input-file-type xmlschema), datamodel-code-generator resolves <xs:include>, <xs:import>, <xs:redefine>, and <xs:override> schemaLocation attributes against the source directory and reads the target with no restriction to the input/base directory. An attacker who controls the input XSD can read arbitrary files via ../ traversal or an absolute path, and the included schema's contents (type names, restrictions, enumerations) are folded into the generated output. Unlike the JSON-Schema $ref path, there is no allow_remote_refs control for XSD, so --no-allow-remote-refs does not mitigate it. This is an unauthenticated path-traversal / information-disclosure issue reachable in the default configuration.
Details
The XSD parser walks include-style children and reads each schemaLocation with only an is_file() check (src/datamodel_code_generator/parser/xmlschema.py):
location = (source_dir / schema_location).resolve() # .resolve() collapses ../, escapes base
if location in seen or not location.is_file():
continue
included_root = self._parse_schema(_read_xml_text(location, self.encoding), location)
schema_location is attacker-controlled and _read_xml_text does path.read_bytes(). Because (source_dir / schema_location).resolve() normalizes .. and accepts absolute paths, the resolved target can be any file the process can read; there is no is_relative_to(base_path) containment (contrast the JSON-Schema HTTP-local branch, which does enforce it). The same unbounded read occurs both during version detection and during the main include-processing pass, so the included content is incorporated into the generated module.
Related vectors that were tested and do NOT apply (stdlib xml.etree.ElementTree is used): external-entity XXE file read does not occur (ElementTree does not fetch external entities), and entity-expansion "billion laughs" is rejected by CPython's expat amplification limit.
PoC
Self-contained reproducer (creates
Details
Original advisory: https://github.com/advisories/GHSA-442q-2j6p-642g
Exploitation outlook
EPSS (FIRST.org) estimates each CVE’s probability of exploitation in the next 30 days — here is the CSIRTS.com read on those numbers.
- Low exploitation riskCVE-2026-553900.36% 30-day exploitation probability — currently an unlikely target, but scores change as exploit code circulates. Riskier than 29% of all scored CVEs.
Referenced CVEs
| CVE | CSIRTS overview | External |
|---|---|---|
| CVE-2026-55390 | coverage & exploitation status | NVD · CVE.org |
Same CVEs, other sources
How other CERTs, PSIRTs and databases cover the vulnerabilities in this advisory.
More from GitHub Security Advisories
- mediumGHSA-jr6p-8pjj-mfx6: Capsule has an incomplete fix of CVE-2026-22872: TenantResource RawItems and Generators s…2026-07-31
- mediumGHSA-68cj-mvg9-rgm2: Capsule: CapsuleConfiguration NodeMetadata regex fields lack webhook validation, allowing…2026-07-31
- mediumGHSA-ff84-5f28-78qj: re2: Out-of-bounds heap read in `exec`/`test`/`match` via attacker-influenced `lastIndex`…2026-07-31
- mediumGHSA-6hxr-mr5r-9836: re2: Global `String.prototype.match` with an empty-matchable pattern never advances → inf…2026-07-31
- mediumGHSA-x83g-979r-f5fh: Sylius Mollie Plugin has unauthenticated IDOR that leaks order token and customer PII2026-07-31