Aug 29, 2026·7 min read·0 visits
Unauthenticated attackers can exploit the MapFish Print endpoint to read local server files and execute SSRF attacks by pointing the GML layer to a crafted remote XML document.
An XML External Entity (XXE) vulnerability in MapFish Print allows unauthenticated remote attackers to perform arbitrary local file disclosure and Server-Side Request Forgery (SSRF) by exploiting GML layer URL parameters in requests submitted to the /api/print3/print endpoint.
MapFish Print is an enterprise-grade, Java-based web component designed for generating and printing high-quality cartographic maps using predefined layout templates. It acts as an integration gateway, pulling geographic metadata, map coordinates, style configurations, and vector layers from diverse sources before compiling them into a final output format such as PDF or PNG. Within this architecture, MapFish Print exposes an unauthenticated web handler at the /api/print3/print endpoint.
To facilitate the printing of rich vector graphics, the application supports multiple layer types. One such supported layer format is the Geography Markup Language (GML), which is an XML-based specification defined by the Open Geospatial Consortium (OGC) to express geographical features. When handling a print job containing a GML layer, the MapFish Print engine resolves a user-supplied URL to retrieve the GML data stream.
Prior to the released security updates, the incoming GML stream was parsed directly by the integrated GeoTools GIS parsing framework without sufficient restrictions. Specifically, the XML parser engine was configured with default settings that allowed XML External Entity (XXE) resolution and did not prevent the parsing of inline Document Type Definitions (DTDs). The exposure of this endpoint and the associated parsing pipeline creates an unauthenticated, remote attack surface.
The root cause of this vulnerability lies in the implementation of the GML layer parsing engine found in core/src/main/java/org/mapfish/print/map/geotools/GmlLayer.java. During a print request, the MapFish server downloads the remote XML document representing the geographical layer from the user-specified GML URL. The application reads the remote document content into memory using its internal HTTP request factory.
Once retrieved, the document string is processed directly through a GeoTools parser instance. In Java environments, XML parsers such as the GeoTools XML parsing wrapper are vulnerable to XML External Entity Injection (CWE-611) if they do not explicitly disable external entity resolution. By default, standard parsers process external entity declarations (<!ENTITY ... SYSTEM ...>) and inline DTDs, resolving the specified files or URLs and substituting their contents into the parsed document.
Furthermore, the application's historical error handling routines exacerbated the severity of this vulnerability. When a parsing exception was encountered during GML compilation, the application constructed an error response that concatenated the raw gmlData string and returned it to the client. This response reflection path allows an attacker to extract the parsed document contents—including any successfully expanded external files—directly within the HTTP response body.
To understand the vulnerability and its remediation, we examine the Java code modifications implemented in GmlLayer.java. In vulnerable versions of the application, the GML data retrieved from the network was passed directly to the GeoTools Parser class without any pre-validation or parser hardening configurations.
The patched code introduces a two-tiered defense. First, a strict pre-validation mechanism is executed before passing the payload to the GeoTools compiler. This is achieved by creating a secure DocumentBuilderFactory that disallows doctype declarations entirely.
// Hardened pre-validation gateway introduced in the patch
private void validateXmlInput(final String gmlData) {
try {
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
// Explicitly disallow DOCTYPE declarations to block XXE payloads
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
factory.setXIncludeAware(false);
factory.setExpandEntityReferences(false);
factory
.newDocumentBuilder()
.parse(new ByteArrayInputStream(gmlData.getBytes(StandardCharsets.UTF_8)));
} catch (ParserConfigurationException | SAXException | IOException e) {
throw new PrintException("Failed to parse GML data", e);
}
}Second, the patch secures the GeoTools parser creation process (createParser) by overriding the runtime EntityResolver2 behavior. This acts as a secondary defense layer in case the primary validation is bypassed or disabled under unique runtime paths.
// Hardened parser creation with overridden EntityResolver
private Parser createParser(final Configuration configuration) {
final Parser parser = new Parser(configuration);
parser.getURIHandlers().addFirst(this.cachingUrihandler);
parser.setEntityResolver(
new EntityResolver2() {
@Override
public InputSource getExternalSubset(final String name, final String baseURI) {
return new InputSource(new StringReader(""));
}
@Override
public InputSource resolveEntity(
final String name,
final String publicId,
final String baseURI,
final String systemId) {
return new InputSource(new StringReader(""));
}
@Override
public InputSource resolveEntity(final String publicId, final String systemId) {
return new InputSource(new StringReader(""));
}
});
return parser;
}Additionally, the exception handling has been sanitized. Previously, error blocks threw exceptions that reflected the input gmlData. The updated code replaces these with standardized generic messages: throw new PrintException("Failed to parse GML data", e);.
An attacker can exploit this vulnerability through a multi-step request workflow. The attack requires that the MapFish Print server has network line-of-sight to an attacker-controlled HTTP server to retrieve the external XML payload, or that the attacker can supply the payload via alternative protocol schemes.
To conduct the attack, the attacker first deploys a malicious GML file on a web server they control. The XML payload is structured with a custom DTD containing an external entity mapping to a local system file, such as /etc/passwd.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE wfs:FeatureCollection [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<wfs:FeatureCollection
xmlns:wfs="http://www.opengis.net/wfs"
xmlns:gml="http://www.opengis.net/gml"
xmlns:topp="http://www.openplans.org/topp">
<gml:featureMember>
<topp:streams fid="streams.1">
<topp:the_geom>
<gml:LineString srsName="EPSG:4326">
<gml:coordinates>0,0 1,1</gml:coordinates>
</gml:LineString>
</topp:the_geom>
<topp:name>&xxe;</topp:name>
</topp:streams>
</gml:featureMember>
</wfs:FeatureCollection>The attacker then sends an HTTP POST request to the /api/print3/print endpoint on the target MapFish server. The request payload defines a GML layer where the URL points to the hosted malicious file. When the MapFish Print server parses the retrieved GML, it expands the &xxe; entity and references the contents of /etc/passwd. Because of the verbose error handling, the file contents are disclosed to the attacker in the subsequent error response.
The impact of CVE-2026-55848 is significant because it can lead to full compromise of confidentiality. MapFish Print instances are typically deployed inside corporate networks or containerized application environments such as Kubernetes to generate internal reports and mapping structures. Consequently, the local files accessible to the application often contain high-value data.
By leveraging the file protocol handler (file:///), an unauthenticated attacker can retrieve sensitive application configuration files, database credentials, internal SSL/TLS certificates, or local operating system user structures. In containerized environments, attackers can extract Kubernetes service-account tokens (/var/run/secrets/kubernetes.io/serviceaccount/token), which may allow them to authenticate directly to the Kubernetes API server and compromise the cluster.
Furthermore, because the application attempts to resolve any URI supplied in the system entity, this vulnerability can also be used to perform Server-Side Request Forgery (SSRF). Attackers can force the MapFish server to make HTTP requests to internal endpoints, enabling network scanning of internal subnets, interaction with local administrative interfaces, or retrieval of cloud instance metadata from providers (such as the AWS IMDS endpoint at http://169.254.169.254).
The primary remediation path is to update MapFish Print to the patched versions. The vulnerabilities have been fully addressed in releases 3.28.30, 3.30.32, 3.31.24, 3.33.16, and 4.0.5. These versions include the hardened parser checks and disabled external entity resolvers.
For deployments where immediate updates are not feasible, several defensive controls can mitigate the risk. Network perimeter rules and firewall configurations should restrict the outbound network access of the MapFish Print application server. If MapFish Print does not require external network connections to retrieve remote map resources, blocking all outbound HTTP/HTTPS connections from the application host will neutralize both remote payload retrieval and SSRF exploit paths.
Additionally, administrators can implement a Web Application Firewall (WAF) rule to inspect POST requests to the /api/print3/print endpoint. The rule should identify and block incoming JSON requests that contain the gml layer type coupled with an external URL structure, or payloads that contain references to unapproved external domains.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
mapfish-print MapFish | >= 3.0.0, < 3.28.30 | 3.28.30 |
mapfish-print MapFish | >= 3.29.0, < 3.30.32 | 3.30.32 |
mapfish-print MapFish | >= 3.31.0, < 3.31.24 | 3.31.24 |
mapfish-print MapFish | >= 3.32.0, < 3.33.16 | 3.33.16 |
mapfish-print MapFish | >= 4.0.0, < 4.0.5 | 4.0.5 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-611 |
| Attack Vector | Network |
| CVSS v3.1 | 8.6 |
| Impact | Arbitrary File Disclosure, SSRF |
| Exploit Status | poc |
| CISA KEV Status | False |
The software associates an XML document with an external entity declaration that contains a URI, which references resources on the local host or network, allowing disclosure of local file contents or server-side request execution.
A comprehensive technical analysis of CVE-2026-55843, an Improper Privilege Management vulnerability (CWE-269) in Snipe-IT versions prior to 8.6.0. The vulnerability allows an authenticated editor or administrator to overwrite and strip the granular or administrative permissions of other users by omitting the permission parameter from profile update payloads. This issue has been resolved in Snipe-IT version 8.6.0.
A critical credential disclosure vulnerability in MariaDB Connector/J allows remote attackers to capture raw database passwords. The driver transmits plaintext passwords prior to verifying TLS certificate fingerprints when configured in ephemeral trust fallback states.
A transport-security omission in the MariaDB Connector/J driver allows remote on-path adversaries or rogue database servers to capture database credentials in cleartext. Under default configurations (sslMode=DISABLE), the driver fails to enforce encrypted channels when negotiating the Pluggable Authentication Module (PAM) 'dialog' plugin, resulting in cleartext transmission of sensitive passwords.
CVE-2026-55858 describes a critical encoding desynchronization vulnerability in MariaDB Connector/J (the official JDBC driver). The vulnerability stems from a mismatch between the driver's static UTF-8 client-side escaping logic and dynamic character set changes initiated on the database server. When the server character set is switched mid-session to an encoding that permits ASCII-overlapping multibyte characters (such as GBK or Big5), an attacker can supply crafted inputs to swallow escaping backslashes, resulting in SQL injection and unauthorized statement execution.
An input validation and encoding desynchronization vulnerability exists in MariaDB Connector/R2DBC versions prior to 1.4.1. The driver assumes all communication utilizes the UTF-8 character set, but fails to account for server-driven mid-session changes to the character_set_client variable. When a change to a multi-byte character set such as GBK or Big5 is induced, the server interprets client-escaped single quotes as part of a multi-byte character. This state desynchronization bypasses standard escaping mechanisms and allows remote unauthenticated attackers to execute arbitrary SQL commands.
A security vulnerability in the MariaDB Connector/R2DBC client driver allows credential theft during the database authentication phase. The client driver does not gate clear-text password authentication plugins on transport encryption, making it possible for on-path attackers or hostile database servers to intercept passwords.