Downloads · 30 days
0
aditya7861/pypmml-xxe-poc
pypmml-xxe-poc is a machine learning model from aditya7861. Use it for the machine learning task on the model card, and read the license before you ship it in a product.
This repository hosts a proof-of-concept model file for a security vulnerability in the pypmml Python package and the pmml4s library it bundles. It is published for coordinated disclosure and security review only. The…
Downloads · 30 days
0
Access
Public
Updated Jun 29, 2026
Repo size
—
Likes
0
Public
Click a slice to open those files.
.py4 KB · 47%
From the Hugging Face model README
This repository hosts a proof-of-concept model file for a security vulnerability in the
pypmml Python package and the pmml4s library it bundles. It is published for coordinated
disclosure and security review only. The PoC is harmless: the included script reads a benign
sentinel file that it creates itself and sends it to a server bound to 127.0.0.1.
pypmml loads PMML model files by passing them to pmml4s, which parses them with a StAX
XMLInputFactory created without any entity hardening (org.pmml4s.xml.pull.scala, the
XMLEventReader constructor). Document type definitions and external entities are resolved by
default. Loading an attacker-supplied .pmml file through the documented public API
(pypmml.Model.load, Model.fromFile, Model.fromString, Model.fromBytes) lets the file:
and exfiltrate the file contents to an attacker host. This is CWE-611 (Improper Restriction of XML External Entity Reference). It does not provide code execution.
malicious.pmml the proof-of-concept model file. Its DOCTYPE points at an external DTD.evil.dtd an example external DTD that reads a local file and exfiltrates it out of band.poc_pypmml_xxe.py a self-contained reproduction. It starts a local listener, generates the
malicious model file, loads it through the public pypmml API, and prints confirmation.python3 -m venv venv
./venv/bin/pip install pypmml==1.5.8
./venv/bin/python poc_pypmml_xxe.py
Expected output ends with:
[+] SSRF (fetched attacker DTD): CONFIRMED
[+] Local file read+exfil (sentinel contents sent to attacker): CONFIRMED
RESULT: VULNERABLE
The Not a valid PMML message during the run is expected and irrelevant: the file is read and
exfiltrated while the document is parsed, before any model is built.
pypmml 1.5.8 (PyPI) and earlier, bundling pmml4s 1.5.8. Confirmed on OpenJDK 21 with the
StAX implementation that ships with the JDK.
Harden the factory in pmml4s (pull.scala) before creating the reader:
val factory = XMLInputFactory.newFactory
factory.setProperty(XMLInputFactory.SUPPORT_DTD, false)
factory.setProperty("javax.xml.stream.isSupportingExternalEntities", false)
Setting SUPPORT_DTD to false disables DTD processing entirely, which PMML does not require.