Views
No views yet
pypmml (which wraps the Scala pmml4s engine) parses the
XML with a StAX XMLInputFactory that leaves DTD processing and external-entity resolution at their
unsafe defaults. A crafted .pmml therefore triggers XML External Entity (XXE) during model
load → arbitrary local file disclosure and SSRF (server-side request to an attacker URL).pypmml==1.5.8 (bundled pmml4s), OpenJDK 26.poc-ssrf-min.pmml — minimal one-hop confirmation (external parameter entity → server fetches your URL).poc-xxe.pmml — references an external DTD (evil.dtd) to perform out-of-band local file read.evil.dtd — the OOB exfil DTD (reads file:///etc/hostname, sends it to your listener).https://abcd.webhook.site.https://YOUR-LISTENER.example in poc-*.pmml and evil.dtd with your listener URL,
and host evil.dtd at <your-listener>/evil.dtd.1pip install pypmml # pulls the pmml4s jar; needs a JRE/JDK on PATH
2python -c "from pypmml import Model; Model.load('poc-xxe.pmml')"evil.dtd, then a /leak?d=<contents of /etc/hostname>
request — i.e. a local file was read and exfiltrated during model load. (pypmml then raises
PMMLError('Not a valid PMML'), but the file read already happened during parsing.)
poc-ssrf-min.pmml just makes the server fetch <your-listener>/SSRF-FIRED = SSRF.pmml4s src/main/scala/org/pmml4s/xml/pull.scala (class XMLEventReader):1val factory = XMLInputFactory.newFactory // no hardening
2val reader = factory.createXMLEventReader(...)XMLInputFactory.SUPPORT_DTD = false nor
XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES = false (the OWASP-required StAX XXE mitigations).
Reachable from every public load entry (Model.load / Model.fromFile / fromString / fromBytes).1factory.setProperty(XMLInputFactory.SUPPORT_DTD, false)
2factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false)