CVE-2024-36401 is an unauthenticated remote code execution vulnerability in GeoServer caused by unsafe evaluation of property names through GeoTools and Apache Commons JXPath. It is not limited to an obscure optional feature, an authenticated administration function, or a specially customized deployment. The official advisory states that the vulnerable XPath handling was incorrectly applied to simple feature types, making the issue relevant to all GeoServer instances that run an affected software stack. Multiple WFS, WMS, and WPS operations can reach the vulnerable behavior. (NVD)
The operational case for urgent action is stronger than the CVSS score alone. CISA added CVE-2024-36401 to the Known Exploited Vulnerabilities Catalog on July 15, 2024, requiring covered federal agencies to remediate it by August 5, 2024. Shadowserver reported observing exploitation attempts against GeoServer WFS endpoints on July 9, six days before the KEV entry. GeoServer later warned that the vulnerability was under active exploitation. (NVD)
The risk did not end with opportunistic scanning. In September 2025, CISA published lessons from an incident response engagement at a U.S. Federal Civilian Executive Branch agency. CISA said threat actors had compromised the agency by exploiting CVE-2024-36401 in an unpatched, public-facing GeoServer instance approximately three weeks before endpoint alerts triggered the response. A second GeoServer instance was later compromised through the same vulnerability. The attackers moved beyond the original servers, used tools and scripts, attempted persistence, and reached additional web and database systems. (CISA)
For defenders, the correct response has two separate tracks:
- Determine whether the deployed GeoServer and GeoTools components are vulnerable.
- Determine whether a vulnerable or previously exposed system has already been compromised.
Installing a patched JAR or upgrading GeoServer addresses the vulnerable code path. It does not erase a web shell, revoke stolen credentials, remove a scheduled task, undo lateral movement, or prove that the host is trustworthy.
Executive risk snapshot
| سؤال | Defensive answer |
|---|---|
| What is the vulnerability? | Eval injection caused by unsafe treatment of externally influenced property names as XPath expressions |
| What component contains the underlying flaw? | GeoTools methods and property accessors that create a Commons JXPath evaluation context |
| Which product exposes the flaw remotely? | GeoServer, through multiple OGC service operations |
| Is authentication required? | لا يوجد |
| Is user interaction required? | لا يوجد |
| Does a default installation matter? | Yes. The advisory describes exploitation against a default GeoServer installation |
| Are only complex feature types affected? | No. The vulnerable handling was incorrectly applied to simple feature types |
| What is the impact? | Arbitrary code execution in the security context of the GeoServer process |
| Is exploitation confirmed? | Yes. CISA added it to KEV, multiple monitoring organizations observed exploitation, and CISA documented a federal agency intrusion |
| What are the original fixed GeoServer releases? | 2.22.6, 2.23.6, 2.24.4, and 2.25.2 |
| What are the corresponding fixed GeoTools releases? | 28.6, 29.6, 30.4, and 31.2 |
| Is there a workaround? | The vulnerable gt-complex component can be removed, or official replacement JARs can be installed, but functionality may break |
| Is patching enough after compromise? | No. Confirmed or suspected compromise requires containment, forensic review, credential rotation, and often a rebuild |
The CNA assigned a CVSS v3.1 score of 9.8 with network access, low attack complexity, no privileges, no user interaction, and high confidentiality, integrity, and availability impact. The later GitHub advisory also presents a CVSS v4 assessment of 9.3. These scores use different CVSS versions and should not be treated as a contradiction about the seriousness of the vulnerability. (NVD)
The GeoServer and GeoTools trust boundary

GeoServer is a Java-based server for publishing and editing geospatial data through open standards. It supports services such as Web Map Service, Web Feature Service, Web Coverage Service, Web Map Tile Service, and Web Processing Service. GeoServer is built on GeoTools, a Java GIS toolkit that supplies data models, filter processing, format support, coordinate operations, and access to spatial data sources. (GeoServer)
That architecture creates a necessary but sensitive trust boundary. A client sends an OGC request containing names of layers, properties, filters, output formats, coordinate systems, rendering options, or processing instructions. GeoServer parses the request and delegates parts of the operation to GeoTools. GeoTools then resolves property paths against feature objects and data stores.
A legitimate property name might be as simple as:
population
A complex feature model might require a nested path such as:
city/address/postalCode
XPath-like processing is useful in the second case because the data does not always look like a flat database row. A complex feature may contain nested objects, namespaces, repeated elements, or relationships. The application needs a way to identify a value several levels below the root object.
The security problem begins when software treats an external property name as a general-purpose expression rather than a constrained data identifier.
The vulnerable path can be summarized as:
Remote OGC request
|
v
Externally influenced property or attribute name
|
v
GeoServer request handling
|
v
GeoTools property accessor
|
v
Apache Commons JXPath context
|
v
XPath function and Java method resolution
XPath is often described as a query language for selecting nodes in XML documents. Commons JXPath extends that model to Java object graphs. It can navigate JavaBeans, collections, maps, and other object structures. The same flexibility becomes dangerous when an expression supplied by an untrusted client can resolve functions or Java classes.
The root issue is therefore not “XML is unsafe” or “GeoServer supports too many standards.” It is a confused trust boundary:
- The caller expected a property identifier.
- The library accepted a more powerful expression.
- The evaluation context retained Java function capabilities.
- Remote input reached that context without sufficient restriction.
This is a classic form of eval injection. The application passes data into an interpreter whose grammar can select behavior, not merely describe a field.
How unsafe XPath evaluation becomes code execution
The GeoTools security advisory identifies several affected methods and classes. They include methods in XmlXpathUtilites, property accessors in FeaturePropertyAccessorFactory و MapPropertyAccessorFactoryو StreamingParser behavior in the XSD module. These methods create or use a JXPathContext to evaluate a string against a Java object or XML document. (جيثب)
Before the security change, affected code paths created a normal JXPath context. In simplified form, the dangerous pattern looked like this:
JXPathContext context = JXPathContext.newContext(targetObject);
context.setLenient(true);
Object value = context.getValue(externallyInfluencedExpression);
The problem is not the getValue call by itself. It is the combination of three conditions:
- The expression is controlled or influenced by an untrusted client.
- The expression is treated as full JXPath syntax rather than a restricted property path.
- The context permits function or Java method resolution.
A blacklist around known dangerous class names would not provide a reliable fix. Expression languages have parsing rules, namespaces, alternate syntax, encoding transformations, type coercion, and library-specific behavior. Filtering one string representation does not remove the interpreter’s capability.
The GeoTools patch took a capability-reduction approach. The change introduced a shared helper named JXPathUtils.newSafeContext. That helper creates a JXPath context, configures namespace handling and lenient behavior as required, and then installs an empty FunctionLibrary:
JXPathContext context = JXPathContext.newContext(contextBean);
context.setLenient(lenient);
// Register required XML namespaces here.
context.setFunctions(new FunctionLibrary());
return context;
The source comment states that the empty function library is set to prevent function calls. Affected call sites were modified to use this safe context rather than creating unrestricted contexts directly. (جيثب)
That distinction matters. The patch does not attempt to predict every malicious expression. It removes an entire category of executable capability from the evaluator.
A secure design for any expression engine should follow the same hierarchy:
- Do not interpret user input when a simple identifier lookup is sufficient.
- When interpretation is necessary, use a restricted grammar.
- Disable functions, reflection, class loading, file access, network access, and process creation by default.
- Allow only explicitly required operations.
- Validate the parsed structure, not just the original string.
- Keep the evaluator in a low-privilege process with limited filesystem and network access.
The patch also helps explain why a reverse proxy rule is an incomplete solution. The vulnerability is inside an expression evaluator. A proxy can block known strings or request shapes, but it cannot reliably reproduce the parser’s complete semantics, all encodings, every OGC request format, and every future variation.
Why simple feature types are affected
One of the most important statements in the official record is that XPath evaluation was intended for complex feature types, such as Application Schema data stores, but was incorrectly applied to simple feature types. The advisory therefore tells defenders to treat all affected GeoServer instances as vulnerable, not only installations using App-Schema. (NVD)
A simple feature usually resembles a flat record:
id
name
population
geometry
A complex feature can contain nested and namespaced values:
building
owner
organization
legalName
address
street
city
geometry
XPath-style navigation is understandable for the second model. It is unnecessary for many operations on the first. The implementation error allowed the more powerful accessor to participate in cases where a simple attribute lookup should have been enough.
This invalidates several common assumptions.
No App-Schema extension does not mean no exposure
The vulnerable handling could be reached for simple feature types. Removing or never installing App-Schema is not, by itself, proof that CVE-2024-36401 does not apply.
A protected administration console does not protect public OGC services
The exploit paths are OGC operations, not an authenticated configuration change in the administrative interface. A deployment can require a password for /web while leaving WMS or WFS services publicly accessible.
Read-only map publication does not eliminate server-side execution risk
A team may consider a public map harmless because users can only request rendered images. The application still parses layer names, properties, styles, filters, and request parameters before rendering the map. A server-side expression injection can occur before any image is returned.
Hidden version information does not remove the flaw
Suppressing the GeoServer version can reduce passive fingerprinting, but attackers can try exploit paths without knowing the exact version. Active exploitation at internet scale rarely depends on perfect inventory information.
Disabling one protocol is not a complete control
The official record lists confirmed paths across WFS, WMS, and WPS. Blocking only WFS does not prove WMS request handling is safe. The correct fix is to remove the vulnerable code by upgrading or applying the official patches.
OGC operations linked to the vulnerable path
The official GeoServer advisory says exploitation was confirmed through the following operations:
- WFS GetFeature
- WFS GetPropertyValue
- WMS GetMap
- WMS GetFeatureInfo
- WMS GetLegendGraphic
- WPS Execute
The public advisory intentionally did not include a complete production-ready exploit request. The absence of an official weaponized proof of concept did not prevent attackers from developing their own methods. (NVD)
| Operation | Normal purpose | Defensive exposure question | Useful log evidence |
|---|---|---|---|
| WFS GetFeature | Retrieves vector features and attributes | Can an unauthenticated internet client submit feature queries? | Query parameters, POST XML, requested property names, filters, response status |
| WFS GetPropertyValue | Retrieves selected property values | Are arbitrary property references accepted from remote clients? | valueReference, type name, parsing errors, response latency |
| WMS GetMap | Renders a map image | Are public requests allowed to control filters, styles, or property expressions? | Layer names, filters, style parameters, request size, 4xx and 5xx responses |
| WMS GetFeatureInfo | Returns information about features near a map coordinate | Can external users influence queried properties and output fields? | Query layers, info format, feature count, exceptions |
| WMS GetLegendGraphic | Produces legend images | Are dynamic style and rule parameters accepted? | Style names, rule parameters, filters, parser errors |
| WPS Execute | Runs geospatial processing operations | Is WPS enabled and reachable by untrusted clients? | Process identifiers, input data, XML bodies, execution duration |
The table should not be used as a list of exploit recipes. Its purpose is to prevent an incomplete inventory. A security team that searches only for /geoserver/wfs may miss an instance exposed under /maps/ows, an API gateway route, or a virtual host that forwards WMS requests to the same backend.
GeoServer can expose OGC services through several URL patterns, depending on the servlet context, proxy, workspace, and configuration. Useful inventory targets include:
/geoserver/
/geoserver/ows
/geoserver/wms
/geoserver/wfs
/geoserver/wps
/<workspace>/wms
/<workspace>/wfs
These paths should be checked only against assets the organization owns or is explicitly authorized to test.
Affected GeoServer and GeoTools versions
The current advisory record lists the following original patched GeoServer releases:
- GeoServer 2.22.6
- GeoServer 2.23.6
- GeoServer 2.24.4
- GeoServer 2.25.2
The corresponding fixed GeoTools versions are:
- GeoTools 28.6
- GeoTools 29.6
- GeoTools 30.4
- GeoTools 31.2
The GitHub advisory represents the affected GeoServer ranges as versions earlier than 2.22.6, versions 2.23.0 through 2.23.5, versions 2.24.0 through 2.24.3, and versions 2.25.0 through 2.25.1. (جيثب)
| Product branch | Vulnerable range | First fixed release in that branch |
|---|---|---|
| GeoServer 2.22 and earlier | Earlier than 2.22.6 | 2.22.6 |
| GeoServer 2.23 | 2.23.0 through 2.23.5 | 2.23.6 |
| GeoServer 2.24 | 2.24.0 through 2.24.3 | 2.24.4 |
| GeoServer 2.25 | 2.25.0 through 2.25.1 | 2.25.2 |
| GeoTools 28 and earlier | Earlier than 28.6 | 28.6 |
| GeoTools 29 | 29.0 through 29.5 | 29.6 |
| GeoTools 30 | 30.0 through 30.3 | 30.4 |
| GeoTools 31 | 31.0 through 31.1 | 31.2 |
Those versions are historical security boundaries, not a recommendation to deploy those old branches today. GeoServer 2.23.6 was released after the 2.23 series had already reached end of life. The project described it as a temporary measure and advised users to move to the then-supported stable or maintenance branches. The same principle applies now: use a currently supported GeoServer release compatible with the environment rather than stopping at the oldest version that contains the CVE fix. (GeoServer)
A scanner result that says “version not detected” should not be interpreted as safe. GeoServer may have version display disabled, custom packaging, backported JARs, or a proxy that removes headers. Conversely, a banner that reports a patched application version is helpful but not conclusive if the deployment contains manually copied, duplicate, or outdated GeoTools libraries.
The most reliable determination combines:
- Deployed GeoServer release
- Actual JAR files loaded under
WEB-INF/lib - Container or package provenance
- Build and release records
- Hashes of locally replaced JARs
- Confirmation that every cluster node uses the same files
Disclosure and exploitation timeline
The sequence of events shows how quickly a critical application vulnerability can move from a coordinated release to active exploitation.
| Date | Event |
|---|---|
| June 13, 2024 | GeoServer 2.23.6 was released as an urgent security update for an end-of-life branch |
| June 18, 2024 | GeoServer 2.24.4 and 2.25.2 were released early to address the critical issue |
| July 1, 2024 | The GeoServer advisory for CVE-2024-36401 was published |
| July 2, 2024 | The GeoTools advisory for CVE-2024-36404 was published |
| July 9, 2024 | Shadowserver first observed exploitation attempts involving POST /geoserver/wfs |
| July 15, 2024 | CISA added CVE-2024-36401 to KEV |
| August 5, 2024 | CISA’s remediation deadline for covered federal agencies |
| September 5, 2024 | Fortinet published research on malware campaigns exploiting the vulnerability |
| September 12, 2024 | GeoServer publicly emphasized that the vulnerability was under active exploitation |
| September 23, 2025 | CISA published an incident response advisory describing a federal agency compromise through unpatched GeoServer instances |
The GeoServer project released fixed versions before publishing full vulnerability details. That is a normal coordinated-disclosure pattern intended to give administrators an opportunity to update. The later activity shows why release monitoring matters. An organization that waits for NVD enrichment, a scanner plugin, KEV inclusion, or a widely circulated exploit may already be behind the exploitation curve. (GeoServer)
The Shadowserver observation is particularly useful for prioritization. It reported exploitation activity on July 9. CISA added the issue to KEV on July 15. KEV is a high-confidence signal that exploitation has occurred, but it is not an early-warning guarantee. Defenders should use KEV as a mandatory prioritization input, not as the sole trigger for patching critical, internet-facing vulnerabilities. (Mastodon hosted on infosec.exchange)
What CISA KEV inclusion changes
A KEV entry means CISA has sufficient evidence that a vulnerability has been exploited in the wild and that remediation guidance exists. For U.S. Federal Civilian Executive Branch agencies covered by Binding Operational Directive 22-01, catalog entries carry mandatory remediation deadlines. For other organizations, KEV remains one of the strongest public prioritization signals available. (CISA)
CVE-2024-36401 was added with the required action:
Apply mitigations per vendor instructions or discontinue use of the product if mitigations are unavailable.
The practical consequence is that CVE-2024-36401 should not sit in a routine quarterly backlog merely because the affected server has low business criticality. A low-value public server can still provide:
- Initial execution inside a trusted network
- Access to database credentials
- Access to geospatial datasets
- A pivot point toward internal services
- A location for web shells and command-and-control tooling
- Compute resources for mining or botnet activity
- A trusted domain and IP address for further attacks
Risk should be evaluated at the attack-path level, not only at the application’s business label.
A public GeoServer used for a small map may run on the same virtual network as production databases. It may have a service account with read access to PostGIS, Oracle Spatial, SQL Server, object storage, or shared files. It may also have outbound internet access and a writable deployment directory. Those environmental factors can turn a “noncritical mapping server” into a useful foothold.
Real-world exploitation and the federal agency intrusion
Fortinet reported campaigns exploiting CVE-2024-36401 to distribute several forms of malware. Its analysis described threat actors using the GeoServer flaw as an entry point for backdoors, cryptocurrency miners, and botnet-related payloads. This activity demonstrates that exploitation was not confined to one actor or one strategic objective. Public-facing GeoServer instances became targets for financially motivated and commodity operations as well as more structured intrusions. (فورتنيت)
The later CISA incident response report provides a more complete example of what can happen after initial access.
CISA said the first public-facing GeoServer instance was compromised on July 11, 2024, through CVE-2024-36401. The vulnerability had been publicly disclosed before that intrusion, and patched releases were available. A second GeoServer instance was compromised on July 24, after the vulnerability had been added to the KEV Catalog. (Infosec Notes)
The attackers did not remain confined to GeoServer. Reporting based on CISA’s advisory described activity involving:
- Deployment or attempted deployment of web shells
- Use of China Chopper
- Execution of scripts and open-source tools
- Host and network discovery
- Movement to a web server and a SQL server
- Scheduled execution and other persistence behavior
- Living-off-the-land techniques
- Continued activity that was not immediately contained after EDR alerts
CISA did not publicly attribute the intrusion to a specific named threat actor in the advisory. Tool choice alone is not sufficient for attribution. China Chopper and public reconnaissance tools are used by multiple groups, and defenders should avoid turning malware family recognition into an unsupported geopolitical conclusion. (تيك رادار)
The report emphasized three organizational failures:
- Critical vulnerabilities were not promptly remediated.
- The incident response plan had not been adequately tested or exercised.
- EDR alerts were not continuously reviewed.
Those failures are connected. Delayed patching created the entry point. Limited alert review increased dwell time. An unpracticed response process made containment and investigation harder.
The incident also reinforces an important post-exploitation principle: the original GeoServer request may be only a small part of the evidence. Once arbitrary code runs, the attacker can shift to host-native tools, scheduled tasks, web shells, credential theft, lateral movement, and outbound command-and-control. Searching only for the original malicious HTTP pattern can miss the larger compromise.
Safe exposure review without weaponized payloads
A safe review should answer five questions:
- Do we operate GeoServer or an application embedding the affected GeoTools modules?
- Is an affected version deployed?
- Can an untrusted client reach the relevant OGC services?
- Are there signs that exploitation was attempted or succeeded?
- Has the remediation been applied consistently and validated?
None of those questions requires sending a remote code execution payload to a production server.
Inventory GeoServer deployments
Start with deployment records, source repositories, container registries, infrastructure manifests, and host filesystems.
Examples for an authorized Linux host:
sudo find /opt /srv /var/lib /var/www /usr/local \
-type f \
\( -name 'geoserver.war' -o -name 'gs-web-app-*.jar' -o -name 'gt-complex-*.jar' \) \
2>/dev/null
Search running Java commands:
ps -eo pid,user,lstart,cmd | grep -Ei \
'geoserver|geoserver\.war|org\.geoserver|start\.jar' | grep -v grep
Inspect listening Java processes:
sudo ss -lntp | grep -i java
For Kubernetes:
kubectl get deployments,statefulsets,pods -A \
-o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,IMAGE:.spec.template.spec.containers[*].image'
Search workload definitions for likely names:
kubectl get deployments,statefulsets -A -o yaml |
grep -Ei 'geoserver|docker\.osgeo\.org/geoserver|geosolutions.*geoserver'
Do not rely only on names. An organization may rename the image, embed GeoServer in a custom WAR, or deploy it behind a generic service name such as maps-api.
Inspect the deployed libraries
For an unpacked deployment:
find /path/to/geoserver/WEB-INF/lib -maxdepth 1 -type f \
\( -name 'gt-complex-*.jar' \
-o -name 'gt-app-schema-*.jar' \
-o -name 'gt-xsd-core-*.jar' \
-o -name 'gs-wfs-*.jar' \
-o -name 'gs-wms-*.jar' \) \
-printf '%f\n' | sort
For a WAR file:
unzip -l /path/to/geoserver.war |
grep -E 'WEB-INF/lib/(gt-complex|gt-app-schema|gt-xsd-core|gs-wfs|gs-wms)-.*\.jar'
Capture hashes:
find /path/to/geoserver/WEB-INF/lib -maxdepth 1 -type f \
\( -name 'gt-complex-*.jar' \
-o -name 'gt-app-schema-*.jar' \
-o -name 'gt-xsd-core-*.jar' \) \
-exec sha256sum {} \;
Look for duplicate versions:
find /path/to/geoserver/WEB-INF/lib -maxdepth 1 -type f -name 'gt-*.jar' \
-printf '%f\n' |
sed -E 's/-[0-9][0-9A-Za-z._-]*\.jar$//' |
sort |
uniq -d
Duplicate JARs can create classpath ambiguity. A team may copy patched files into the directory without removing older versions, or an extension may carry a second dependency. The application version shown in the interface does not prove which class was loaded at runtime.
Review container contents
For a local image:
docker run --rm --entrypoint sh your-approved-geoserver-image:tag -c '
find / -type f \( \
-name "gt-complex-*.jar" -o \
-name "gt-app-schema-*.jar" -o \
-name "gt-xsd-core-*.jar" \
\) 2>/dev/null
'
Generate an SBOM using an approved internal tool:
syft your-approved-geoserver-image:tag -o cyclonedx-json > geoserver-sbom.json
Search the SBOM:
jq -r '
.components[]?
| select(
(.name | test("gt-complex|gt-app-schema|gt-xsd-core|geoserver"; "i"))
)
| [.name, .version, .purl]
| @tsv
' geoserver-sbom.json
SBOM results are useful, but verify them against the actual container filesystem. Java component detection can be incomplete when packages are renamed, shaded, manually copied, or embedded in a WAR.
Confirm service exposure with benign requests
On an isolated lab instance or an authorized internal target, request capabilities rather than injecting an expression:
curl --fail-with-body --silent --show-error \
'http://127.0.0.1:8080/geoserver/ows?service=WMS&version=1.3.0&request=GetCapabilities' \
-o wms-capabilities.xml
For WFS:
curl --fail-with-body --silent --show-error \
'http://127.0.0.1:8080/geoserver/ows?service=WFS&version=2.0.0&request=GetCapabilities' \
-o wfs-capabilities.xml
For WPS:
curl --fail-with-body --silent --show-error \
'http://127.0.0.1:8080/geoserver/ows?service=WPS&version=1.0.0&request=GetCapabilities' \
-o wps-capabilities.xml
These requests answer whether the service is reachable and enabled. They do not prove vulnerability, and they do not attempt execution.
Record:
- The requested hostname
- Proxy and load-balancer path
- Source network
- Authentication behavior
- HTTP status
- Backend node
- Response timestamp
- Whether workspace-specific routes are also enabled
A request returning 401 أو 403 from one path does not prove that every alternate route is protected. Check the actual reverse-proxy configuration, not only a single URL.
Review edge and identity controls
For each deployment, determine:
- Is the endpoint reachable from the public internet?
- Does the proxy require authentication for OGC requests?
- Are WMS and WFS intentionally public?
- Is WPS enabled?
- Are workspace-specific services exposed?
- Is the administrative interface reachable from the same network?
- Can the GeoServer process write to the deployed web application?
- Can it create files in
/tmp, home directories, or mounted volumes? - Can it reach the internet?
- Can it reach databases, directory services, secrets managers, or cloud metadata?
- Does the service account hold reusable credentials?
The answer may change incident priority even when the software version is the same.
A safe local PoC for the evaluator boundary
The following demonstration is deliberately limited. It does not send a request to GeoServer, start an operating-system process, read a file, contact a network service, or execute a command. It runs only in a local Java test environment and uses a short thread delay to show that a default JXPath context can resolve a Java method while a context with an empty function library blocks that capability.
This example is useful for understanding the patch design. It is not a production vulnerability scanner.
import org.apache.commons.jxpath.FunctionLibrary;
import org.apache.commons.jxpath.JXPathContext;
public final class SafeJXPathBoundaryDemo {
private static JXPathContext createRestrictedContext(Object root) {
JXPathContext context = JXPathContext.newContext(root);
// An empty function library removes Java function resolution.
context.setFunctions(new FunctionLibrary());
return context;
}
public static void main(String[] args) {
Object harmlessRoot = new Object();
String demonstrationExpression =
"java.lang.Thread.sleep(25)";
long unsafeStarted = System.nanoTime();
try {
JXPathContext defaultContext =
JXPathContext.newContext(harmlessRoot);
defaultContext.getValue(demonstrationExpression);
long elapsedMillis =
(System.nanoTime() - unsafeStarted) / 1_000_000;
System.out.println(
"Default context accepted a Java method expression. "
+ "Elapsed time: "
+ elapsedMillis
+ " ms");
} catch (RuntimeException exception) {
System.out.println(
"Default-context result depends on the installed "
+ "JXPath build and configuration: "
+ exception.getClass().getName());
}
try {
JXPathContext restrictedContext =
createRestrictedContext(harmlessRoot);
restrictedContext.getValue(demonstrationExpression);
throw new IllegalStateException(
"Restricted context unexpectedly allowed a function");
} catch (RuntimeException expected) {
System.out.println(
"Restricted context blocked function resolution: "
+ expected.getClass().getName());
}
}
}
The official GeoTools advisory used a similar time-delay concept in its local StreamingParser demonstration. The production patch then applied the safer design globally by constructing restricted contexts with an empty function library. (جيثب)
The boundaries of this demonstration are important:
- It proves only that expression evaluators can expose more capability than a property lookup requires.
- It does not reproduce an HTTP exploit path.
- It does not identify whether a remote GeoServer is vulnerable.
- It does not test a production target.
- It should be run only in a disposable local development environment.
- A successful delay is not needed to justify patching a version already listed as affected.
- A failed local demonstration does not overrule the official affected-version record.
For production systems, version and dependency verification is safer and more authoritative than attempting RCE.
Detection in web and reverse-proxy logs
Detection should combine request patterns with host behavior. A request signature alone may be incomplete, while a Java process spawning a shell is highly suspicious even when the original request is missing.
Start by identifying requests to GeoServer OGC endpoints:
grep -Ei \
'/(geoserver/)?(ows|wfs|wms|wps)(\?|/|[[:space:]])' \
/var/log/nginx/access.log
Review POST requests:
awk '$6 ~ /"POST/ && $7 ~ /(geoserver|\/ows|\/wfs|\/wms|\/wps)/' \
/var/log/nginx/access.log
Look for bursts across multiple operations:
grep -Ei '/(geoserver/)?(ows|wfs|wms|wps)' /var/log/nginx/access.log |
awk '{print $1, $4, $7}' |
sort |
uniq -c |
sort -nr |
head -100
Potentially suspicious characteristics include:
- Property or value-reference parameters containing function-call syntax
- Java package-like identifiers where a normal GIS property name is expected
- Heavily encoded parentheses, colons, brackets, or method separators
- Very long property names
- The same source trying several WFS, WMS, and WPS operations
- Repeated 500 responses followed by a successful response
- Requests followed by a new outbound connection from the GeoServer host
- Requests followed by Java spawning a command interpreter
- Sudden response-time changes associated with unusual property expressions
A generic SIEM query can begin with the endpoint and method rather than a brittle full payload signature:
http.request.method = "POST"
AND url.path matches /(?i)(\/geoserver)?\/(ows|wfs|wms|wps)/
AND (
http.request.body matches /(?i)(java\.lang|javax\.|jdk\.)/
OR url.query matches /(?i)(java\.lang|javax\.|jdk\.)/
OR http.request.body matches /%28|%29|\(|\)/
)
This query is intentionally broad. Parentheses and encoded characters can appear in legitimate OGC filters, so matches require context. A rule should not automatically block or declare compromise solely because a GIS query contains expression syntax.
Improve confidence by correlating with:
- GeoServer or JXPath exceptions
- Process-creation telemetry
- File creation under web roots
- New scheduled tasks
- Network connections from the Java process
- Threat-intelligence matches
- Known exploitation time windows
Example Splunk-style correlation
index=proxy
(http_method=POST)
(uri_path="*/geoserver/*" OR uri_path="*/ows"
OR uri_path="*/wfs" OR uri_path="*/wms" OR uri_path="*/wps")
(
request_body="*java.lang*"
OR request_body="*javax.*"
OR query_string="*java.lang*"
OR query_string="*javax.*"
)
| stats
count
values(uri_path) AS paths
values(status) AS statuses
min(_time) AS first_seen
max(_time) AS last_seen
BY src_ip, dest_host
Treat this as a starting point. Field names, body capture, URL decoding, privacy restrictions, and proxy behavior differ by environment.
Example Elastic-style query
http.request.method: "POST" and
url.path: (
*"/geoserver/"* or
*"/ows"* or
*"/wfs"* or
*"/wms"* or
*"/wps"*
) and
(
url.query: (*"java.lang"* or *"javax."*)
or
http.request.body.content: (*"java.lang"* or *"javax."*)
)
If the proxy does not retain request bodies, GeoServer application logs, WAF logs, packet captures retained under policy, or upstream gateway telemetry may provide additional context.
Detection in GeoServer and Java logs
Search GeoServer, servlet-container, and application logs for:
JXPathJXPathContextFunctionLibraryFeaturePropertyAccessorXmlXpathUtilitesStreamingParserIllegalArgumentExceptionInvocationTargetException- Property access errors
- Unexpected class-loading exceptions
- Repeated OGC service exceptions from the same source
- Abrupt application restarts
مثال على ذلك:
grep -RniE \
'JXPath|FeaturePropertyAccessor|XmlXpath|StreamingParser|InvocationTargetException' \
/var/log/geoserver \
/var/log/tomcat* \
/opt/geoserver/logs \
2>/dev/null
Review timestamps around suspicious web requests:
journalctl -u geoserver \
--since '2024-07-01 00:00:00' \
--until '2024-08-01 00:00:00'
Adapt the range to the organization’s actual exposure period. If an instance remained vulnerable for months, a narrow search around public disclosure is insufficient.
Application exceptions are not proof of exploitation. Attackers may generate errors while probing, and legitimate malformed GIS queries can also produce stack traces. The strongest signals appear when application events align with host activity.
Hunt for Java child processes
A GeoServer process normally performs Java application work. It should not routinely start shells, download utilities, scripting engines, or operating-system reconnaissance tools.
High-value EDR logic includes:
Parent process:
java
java.exe
Suspicious child process:
sh
bash
dash
zsh
cmd.exe
powershell.exe
pwsh
wscript.exe
cscript.exe
curl
wget
certutil.exe
bitsadmin.exe
python
python3
perl
nc
ncat
A simplified Sigma-style rule:
title: Suspicious Shell or Downloader Spawned by Java
status: experimental
logsource:
category: process_creation
detection:
parent_java:
ParentImage|endswith:
- '/java'
- '\java.exe'
suspicious_child:
Image|endswith:
- '/sh'
- '/bash'
- '/curl'
- '/wget'
- '/python'
- '/python3'
- '\cmd.exe'
- '\powershell.exe'
- '\pwsh.exe'
- '\certutil.exe'
condition: parent_java and suspicious_child
falsepositives:
- Approved administration or application jobs that intentionally launch tools
level: high
Tune the rule with:
- GeoServer service account
- GeoServer installation path
- Servlet container command line
- Known maintenance scripts
- Container ID
- Host role
A Java-to-shell event on a build server may be normal. The same event from a public GeoServer process is materially more suspicious.
Hunt for filesystem persistence and web shells
Check for recently modified files in deployed application directories:
sudo find /path/to/tomcat/webapps /path/to/geoserver \
-type f \
-mtime -30 \
-printf '%TY-%Tm-%Td %TH:%TM:%TS %u %g %m %p\n' |
sort
Search for unexpected server-side pages:
sudo find /path/to/tomcat/webapps \
-type f \
\( -name '*.jsp' -o -name '*.jspx' -o -name '*.war' \) \
-printf '%TY-%Tm-%Td %TH:%TM:%TS %u %g %m %p\n' |
sort
Review files writable by the GeoServer account:
sudo -u geoserver find /path/to/tomcat/webapps /path/to/geoserver \
-type f -writable -print 2>/dev/null
Inspect persistence locations:
sudo crontab -l
sudo crontab -u geoserver -l 2>/dev/null
sudo systemctl list-unit-files --state=enabled
sudo find /etc/systemd/system /usr/lib/systemd/system \
-type f -mtime -30 -print
sudo find /etc/cron* /var/spool/cron \
-type f -mtime -30 -print 2>/dev/null
On Windows, review:
- Scheduled Tasks
- Services
- Startup folders
- Run and RunOnce registry keys
- IIS or Tomcat web roots
- PowerShell operational logs
- Prefetch and Amcache
- Java child processes
- Newly created local accounts
Do not delete suspicious files before preserving metadata and content. Copy them to a controlled evidence location, calculate hashes, record timestamps, and document the source path.
Hunt for outbound and lateral activity
A compromised GeoServer can become an internal pivot.
Review connections owned by Java:
sudo lsof -nP -i |
awk 'tolower($1) ~ /^java/ {print}'
Review current sockets with process data:
sudo ss -tpna | grep -i java
Search firewall and flow logs for:
- New outbound destinations
- DNS queries for recently registered domains
- Connections to raw IP addresses
- Mining-pool protocols
- High-numbered ports
- Repeated connections at fixed intervals
- Connections from GeoServer to internal SSH, SMB, RDP, WinRM, database, or management services
- Scanning patterns across internal address ranges
Compare behavior to a known-good period. GeoServer may legitimately connect to databases, remote WMS services, object storage, identity providers, and license-independent external data feeds. The meaningful question is whether the destination, port, timing, process, and volume match the approved application design.
Distinguishing probing from compromise

| الأدلة | Likely interpretation | الإجراء الموصى به |
|---|---|---|
| Vulnerable version with no retained logs | Exposure cannot be excluded | Patch immediately, increase monitoring, assess historical reachability |
| Suspicious OGC request rejected with a parser error | Possible probing | Preserve request, block source where appropriate, review host telemetry |
| Repeated exploit-like requests across several endpoints | Active exploitation attempt | Escalate investigation, inspect process and network telemetry |
| Java process starts a shell or downloader | Strong compromise indicator | Isolate host and initiate incident response |
| New JSP or WAR file under the deployment directory | Likely persistence or post-exploitation artifact | Preserve evidence, isolate, scope adjacent systems |
| New scheduled task owned by the GeoServer account | Likely persistence | Treat as confirmed compromise unless proven authorized |
| GeoServer host connects to new external infrastructure | Possible command-and-control or payload retrieval | Correlate with process and DNS evidence |
| Only the version banner indicates exposure | Vulnerability evidence, not compromise evidence | Verify files and patch status |
| Patched JAR present alongside an older duplicate JAR | Remediation uncertain | Determine actual class loading and correct the deployment |
| WAF blocked known signatures | Partial compensating control | Patch remains required |
A lack of evidence is not evidence of no compromise when logs are missing, overwritten, stored only on the affected host, or not continuously reviewed. CISA’s incident report specifically emphasized centralized, out-of-band logging and continuous alert review. (LinkedIn)
Incident response when exploitation is suspected
Preserve evidence before making destructive changes
Collect:
- Proxy and load-balancer logs
- WAF logs
- GeoServer request and application logs
- Servlet-container logs
- EDR events
- Process trees
- Network connections
- DNS history
- Recently modified files
- Scheduled tasks
- Service definitions
- Authentication logs
- Container runtime events
- Kubernetes audit logs
- Cloud control-plane logs
- Database connection logs
When possible, capture volatile evidence before rebooting:
date -u
ps auxwwf
ss -tpna
lsof -nP
mount
df -h
last -F
who -a
Store output outside the potentially compromised host.
Contain the server
Containment options include:
- Remove public routing
- Restrict the load balancer to an incident-response source range
- Isolate the host or namespace
- Block outbound internet access
- Block lateral access except to evidence-collection systems
- Snapshot disks according to forensic policy
- Preserve the container image and writable layer
- Prevent automated scaling from destroying affected instances
Do not allow a compromised node to remain publicly reachable merely to observe the attacker unless the activity is part of a formally approved, legally reviewed incident-response operation.
Rotate reachable credentials
GeoServer frequently stores or can access credentials for:
- PostGIS
- أوراكل
- SQL Server
- LDAP
- Object storage
- Remote WMS and WFS services
- API gateways
- Cloud services
- Shared filesystems
- Monitoring platforms
Rotate credentials that were present on the host or accessible to the service account. Do not assume the attacker viewed only GeoServer configuration files. Arbitrary code execution permits reading any file and environment variable available to the process.
مراجعة:
sudo -u geoserver env
For a running process, authorized responders can inspect the process environment through approved forensic tooling. Be careful: environment data may contain secrets and must be handled accordingly.
Scope adjacent systems
The CISA case included movement beyond the original GeoServer instances. Investigate systems that accepted connections from the affected host, especially:
- Web servers
- SQL servers
- Database clusters
- File servers
- Domain services
- Jump hosts
- Container control planes
- Monitoring systems
- Backup servers
Search for shared indicators, accounts, SSH keys, scripts, web shells, task names, destination addresses, and command lines.
Rebuild when trust is lost
A confirmed web shell, unauthorized scheduled task, malicious binary, credential theft, or unexplained root-level activity generally justifies rebuilding the server from a trusted image.
A suitable recovery sequence is:
- Preserve evidence.
- Build a clean host or image from verified source artifacts.
- Install a currently supported GeoServer release.
- Restore only reviewed configuration and data.
- Rotate credentials.
- apply least-privilege and network controls.
- Validate dependencies and hashes.
- Test required OGC services.
- Reconnect the host under heightened monitoring.
- Continue hunting for lateral activity.
Deleting one malicious JSP and restarting Tomcat is not a reliable recovery method.
Patching and mitigation choices
Upgrade to a supported GeoServer release
The preferred remediation is to upgrade to a currently supported GeoServer version that includes the security fix. The original fixed releases were 2.22.6, 2.23.6, 2.24.4, and 2.25.2, but those should now be treated as historical minimum boundaries. GeoServer’s release process maintains stable and maintenance branches for limited periods, and the project recommends regular upgrades rather than indefinite use of an old security branch. (GeoServer)
Before upgrading:
- Back up the data directory
- Export relevant configuration
- Record installed extensions
- Record Java and servlet-container versions
- Record reverse-proxy behavior
- Capture current capabilities documents
- Test custom styles, stores, security rules, and plugins
- Review release-specific upgrade instructions
After upgrading:
- Re-enumerate JAR files
- Confirm no vulnerable duplicates remain
- Test WMS, WFS, WCS, WMTS, and WPS only where required
- Validate authentication and authorization
- Compare capabilities output
- Review startup logs for extension failures
- Confirm every node uses the new image
- Retest external exposure
Use official replacement JARs only as a controlled emergency path
The GeoServer advisory provided patched replacement JARs for several older releases. The package contains patched versions of:
gt-app-schemagt-complexgt-xsd-core
The advisory states that the replacement files configure Commons JXPath with an empty function list before use. (جيثب)
A controlled replacement process should include:
systemctl stop geoserver
Back up the original files:
mkdir -p /secure-backup/geoserver-cve-2024-36401
cp -a /path/to/geoserver/WEB-INF/lib/gt-app-schema-*.jar \
/path/to/geoserver/WEB-INF/lib/gt-complex-*.jar \
/path/to/geoserver/WEB-INF/lib/gt-xsd-core-*.jar \
/secure-backup/geoserver-cve-2024-36401/
Record hashes:
sha256sum /secure-backup/geoserver-cve-2024-36401/*.jar \
> /secure-backup/geoserver-cve-2024-36401/SHA256SUMS.txt
Install only the official files for the exact deployed branch. Remove old JARs rather than leaving duplicates. Restart and review logs:
systemctl start geoserver
journalctl -u geoserver -n 300 --no-pager
A manual JAR swap introduces operational risks:
- Wrong branch
- Incomplete three-file replacement
- Duplicate versions
- Cluster nodes with different files
- Container restart restoring the vulnerable image
- Extension incompatibility
- Package manager overwriting the fix
- No durable record of the change
Use it as a temporary bridge to a full supported upgrade, not as an invisible permanent fork.
Remove gt-complex only when the functional impact is understood
The official workaround allows administrators to remove gt-complex-x.y.jar. This removes vulnerable functionality but can prevent GeoServer from starting or break modules that depend on it. The advisory specifically identifies dependencies including:
- Application Schema
- Catalog Services for the Web
- MongoDB Data Store
- Features Templating
- OGC API modules
- Smart Data Loader
- SOLR Data Store
The list is not guaranteed to include every dependency. (جيثب)
For a WAR deployment, the official process is broadly:
- Stop the application server.
- Extract the WAR.
- Remove
WEB-INF/lib/gt-complex-x.y.jar. - Repackage the WAR.
- Restart the application server.
For a binary Jetty deployment:
- Stop Jetty.
- Remove the JAR from
webapps/geoserver/WEB-INF/lib. - Restart Jetty.
Validate startup, capabilities, stores, extensions, and production workflows before returning the service to users.
Do not treat a WAF rule as the patch
A WAF can reduce exposure during an emergency by:
- Blocking unneeded OGC services
- Restricting methods
- Enforcing authentication
- Limiting source networks
- Rejecting obvious Java class references
- Applying request-size and rate limits
It cannot guarantee that every dangerous expression is blocked. OGC requests legitimately contain complex syntax, XML, filters, namespaces, and encoded values. A rule strict enough to block every unusual expression may break legitimate GIS clients, while a permissive rule can miss alternate syntax.
Use a WAF as a compensating control while the upgrade is prepared. Do not close the vulnerability ticket solely because the WAF logs a blocked test.
Hardening GeoServer after remediation
Publish only required services
Disable services that the deployment does not need. WPS deserves particular scrutiny because it is designed to execute server-side geospatial processes. A public map viewer may need WMS and WMTS but not WFS-T or WPS.
Review whether users require:
- WMS
- WFS
- WFS-T
- WCS
- WPS
- CSW
- REST configuration
- OGC API modules
- Demo endpoints
Removing unused functionality reduces both attack surface and monitoring noise.
Separate public services from administration
Use a reverse proxy or network policy so that:
- Public users can reach only approved OGC routes
- The administration interface is restricted to a management network
- REST configuration requires strong authentication
- Internal health and diagnostic endpoints are not internet accessible
- Workspace-specific routes follow the same policy
Do not rely on obscurity or a nonstandard URL.
Run the service with minimal privileges
The GeoServer process should not run as root or a domain administrator. It should have:
- Read access to required application files
- Write access only to required data and cache locations
- No write access to the deployed WAR or web root where possible
- No access to unrelated home directories
- No SSH private keys
- No package-management privileges
- No ability to modify system services
- No unrestricted access to container or cloud control planes
A read-only container root filesystem can significantly limit post-exploitation file placement:
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
Provide writable ephemeral or persistent volumes only for locations GeoServer actually requires.
Restrict outbound access
Many server compromises become more damaging because the application can download tools, contact command-and-control infrastructure, or scan internal networks.
Use firewall or Kubernetes egress policy to allow only:
- Required databases
- Approved identity services
- Approved remote geospatial services
- Monitoring endpoints
- Explicit update or artifact repositories when operationally necessary
Block direct internet egress where the application does not require it.
Protect data-source credentials
Store credentials outside the deployable application when the platform supports a safer secret mechanism. Use accounts limited to the required schemas and operations.
A public map service may need only read access. Do not give it:
- Database administration rights
- Operating-system authentication rights
- Cross-database access
- Unrestricted network privileges
- Shared credentials used by unrelated applications
Rotate credentials after any suspected RCE exposure.
Centralize logs away from the host
Send:
- Reverse-proxy access logs
- GeoServer logs
- Tomcat or Jetty logs
- Process telemetry
- DNS logs
- Network flows
- Authentication logs
- Kubernetes audit events
to a centralized system that the GeoServer account cannot modify.
CISA’s incident lessons emphasized verbose logging, centralized out-of-band aggregation, and continuous review. Logs stored only on a compromised server can be deleted or altered. (LinkedIn)
Maintain a component inventory
Track:
- GeoServer version
- GeoTools version
- GeoWebCache version
- Java version
- Servlet container
- Installed extensions
- Community modules
- JDBC drivers
- Authentication plugins
- Custom JARs
- Container base image
- Deployment hash
CVE-2024-36401 illustrates why an application inventory alone is incomplete. The remote product was GeoServer, while the vulnerable execution behavior originated in GeoTools and JXPath context handling.
Validation after remediation
A proper retest verifies more than a new version string.
File-level checks
Confirm that:
- Vulnerable JAR versions are absent
- Patched files exist
- No duplicate GeoTools libraries remain
- All nodes have identical hashes
- Container images are immutable and traceable
- Deployment automation points to the patched artifact
مثال على ذلك:
find /path/to/geoserver/WEB-INF/lib -maxdepth 1 -type f \
\( -name 'gt-complex-*.jar' \
-o -name 'gt-app-schema-*.jar' \
-o -name 'gt-xsd-core-*.jar' \) \
-exec sha256sum {} \; |
sort
Functional checks
Test legitimate operations:
- WMS GetCapabilities
- WMS GetMap for an approved layer
- WFS GetCapabilities
- WFS GetFeature with a normal property list
- WPS GetCapabilities if WPS is required
- Authentication and authorization
- App-Schema or CSW functionality if used
- Custom extensions
Security-control checks
Confirm:
- Public routing matches the intended design
- Administration routes are restricted
- WPS is disabled or protected when unnecessary
- The service account cannot modify the application deployment
- Outbound network rules work
- Java-to-shell alerts trigger
- Logs reach the central platform
- Incident responders can identify the deployment owner
Evidence-driven retesting
The final record should contain:
- Asset identifier
- Owner
- Authorized scope
- Original vulnerable version
- Actual vulnerable JAR evidence
- External exposure evidence
- Change ticket
- Patched artifact hash
- Deployment time
- Functional test results
- Security-control test results
- Log and EDR validation
- Residual risk
- Investigator and approval
Teams using authorized, agent-assisted testing workflows can use platforms such as بنليجنت to organize asset checks, tool output, request evidence, and remediation retests. The useful outcome is not an automated “vulnerable” label by itself, but a reproducible chain showing what was deployed, what was reachable, what changed, and why the final conclusion is justified. Penligent’s public product page describes evidence-first results and traceable proof as parts of its testing workflow. (بنليجنت)
Automation must remain constrained to owned or explicitly authorized targets. It should prefer inventory and non-destructive validation when the vulnerability can produce unauthenticated RCE.
Common remediation failures
Patching only the internet-facing load-balancer node
A cluster may contain internal nodes, standby nodes, disaster-recovery instances, or old containers not currently receiving traffic. Every copy must be patched or removed.
Updating the WAR but not the running deployment
Tomcat may continue using an already extracted directory under webapps/geoserver. Replacing geoserver.war without confirming redeployment can leave old classes active.
Replacing one JAR instead of all required JARs
The official patch package includes gt-app-schema, gt-complexو gt-xsd-core. Partial replacement can leave another vulnerable code path or create incompatible module versions.
Leaving duplicate JARs
Two versions of the same library can produce unpredictable class loading. Remove the superseded file and confirm the runtime classpath.
Patching the container interactively
A manual change inside a running container disappears after restart or rescheduling. Fix the image definition, rebuild, sign or record the image, update the deployment, and verify every pod.
Closing the issue because the version page is hidden
Hiding version information is a minor hardening measure, not remediation.
Closing the issue because no exploit request was found
Logs may not include bodies, may have expired, or may not cover alternate paths. Absence of a known payload is not proof that an exposed vulnerable system was never attacked.
Patching after compromise without rotating credentials
RCE allows the attacker to read application configuration and environment secrets. Patch status does not invalidate copied credentials.
Restoring an old vulnerable snapshot
Disaster-recovery procedures frequently reintroduce patched vulnerabilities. Update golden images, backups, templates, Terraform variables, Helm charts, and recovery documentation.
Related vulnerabilities and the broader lesson
CVE-2024-36401 is part of a broader class of geospatial application vulnerabilities in which expressive OGC inputs cross into powerful backend interpreters.
| مكافحة التطرف العنيف | المكوّن | Security issue | Why it is relevant |
|---|---|---|---|
| CVE-2024-36401 | GeoServer | Unauthenticated RCE through unsafe property-name evaluation | Remote product-level exposure discussed here |
| CVE-2024-36404 | GeoTools | RCE when affected GeoTools functions evaluate untrusted XPath expressions | Direct library-level root cause |
| CVE-2023-25157 | GeoServer | SQL injection through OGC Filter and function expressions | Another case where expressive geospatial filters crossed an unsafe backend boundary |
| CVE-2023-25158 | GeoTools | SQL injection in JDBCDataStore implementations processing OGC filters | Library-level counterpart to the GeoServer SQL injection issue |
| CVE-2024-29198 | GeoServer | Unauthenticated SSRF through TestWfsPost | Shows that test and demonstration functionality can expose server-side network capabilities |
| CVE-2022-41852 | Commons JXPath ecosystem | Originally described as unsafe handling of untrusted XPath expressions | Historically relevant to the JXPath risk discussion, but later records disagree about its validity |
CVE-2024-36404
CVE-2024-36404 is the GeoTools advisory underlying the GeoServer issue. It affects applications that use specified GeoTools functionality to evaluate XPath expressions derived from user input. GeoTools versions 28.6, 29.6, 30.4, and 31.2 contain the relevant fix. Applications embedding GeoTools outside GeoServer should review whether they use the affected modules and methods. (جيثب)
The distinction between CVE-2024-36401 and CVE-2024-36404 helps vulnerability management teams map risk correctly:
- CVE-2024-36404 identifies the vulnerable library behavior.
- CVE-2024-36401 identifies how GeoServer remotely exposes that behavior through OGC requests.
A software composition tool may report the library CVE, while an external scanner reports the GeoServer CVE. They can describe the same underlying weakness at different product layers.
CVE-2023-25157 and CVE-2023-25158
GeoServer and GeoTools previously addressed SQL injection vulnerabilities involving OGC Filter and function expressions. GeoTools supports translating OGC filters into queries against JDBC data stores. Certain functions or filter structures were not safely encoded for specific database dialects, allowing crafted input to alter SQL behavior. The GeoServer project published CVE-2023-25157 for the remotely exposed product issue, while CVE-2023-25158 covered GeoTools. (GeoServer)
The direct impacts differ from CVE-2024-36401, but the engineering lesson is similar. A filter language that appears to describe geospatial data can eventually reach:
- SQL generation
- XPath evaluation
- Rendering transformations
- Processing functions
- Remote data stores
Each translation boundary must reduce capability and preserve the intended grammar.
CVE-2024-29198
CVE-2024-29198 concerns unauthenticated server-side request forgery through GeoServer’s TestWfsPost functionality. GeoServer 2.24.4 and 2.25.2 included fixes for this issue alongside CVE-2024-36401. The release notes explain that the demo request page was rewritten and the old TestWfsPost servlet was removed. (GeoServer)
Its relevance is operational. Administrators often focus on primary WMS and WFS services but overlook:
- Demo pages
- Request builders
- Test servlets
- Status pages
- Extension endpoints
- Community modules
A complete exposure review must include auxiliary functionality, not only the main API.
The disputed status of CVE-2022-41852
CVE-2022-41852 was originally described in NVD as an RCE risk when Commons JXPath evaluates untrusted XPath expressions. The description states that an expression could select Java classes from the classpath and lead to execution. (NVD)
Other downstream records later marked the advisory as withdrawn or a false positive. GitLab’s advisory database labels it a false positive, and some vendor records state that the CNA withdrew it after further investigation. (GitLab Advisory Database)
That disagreement should be represented accurately. It would be misleading to claim that CVE-2022-41852 provides an undisputed, independently patched Commons JXPath vulnerability that directly resolves CVE-2024-36401.
The concrete facts relevant to GeoServer are clearer:
- GeoTools used Commons JXPath contexts in ways that permitted Java function resolution.
- Untrusted GeoServer request data could reach those contexts.
- GeoTools fixed the issue by creating restricted contexts with an empty function library.
- GeoServer shipped the corrected GeoTools versions and replacement JARs.
The secure engineering conclusion does not depend on treating CVE-2022-41852 as an uncontested vulnerability record. Do not evaluate untrusted expressions in a context that can resolve Java functions.
الأسئلة الشائعة
Is every GeoServer installation affected by CVE-2024-36401?
- Every installation running an affected GeoServer and GeoTools combination should be treated as vulnerable. The official record says the unsafe XPath evaluation was incorrectly applied to simple feature types, making the issue relevant beyond App-Schema deployments.
- The original fixed GeoServer releases were 2.22.6, 2.23.6, 2.24.4, and 2.25.2.
- A newer supported release should be used today. The historical fixed versions identify the security boundary, not the best current deployment target.
- A custom backport may be safe only when it can be verified. Confirm the actual
gt-complex,gt-app-schemaوgt-xsd-corefiles and their provenance. - An unreachable development instance has lower immediate exposure but still needs remediation. It may later become reachable, be copied into production, or remain accessible from a compromised internal host. (NVD)
Can authentication on the GeoServer admin console stop the exploit?
- Not by itself. The vulnerable paths are OGC service requests such as WFS, WMS, and WPS operations.
- The administration console and public service endpoints can have different access policies.
- A password on
/geoserver/webdoes not prove that/geoserver/ows,/wfsأو/wmsrequires authentication. - Network restrictions around all OGC routes can reduce exposure.
- The official software fix is still required because a future routing change or internal attacker could reach the vulnerable code.
How can I check exposure without sending an exploit?
- Inventory the deployed GeoServer version.
- Inspect the actual GeoTools JARs under
WEB-INF/lib. - Check container SBOMs and filesystem contents.
- Use benign GetCapabilities requests to confirm which OGC services are reachable.
- Review reverse-proxy and identity rules.
- Check whether WFS, WMS, or WPS can be reached by an unauthenticated client.
- Search historical logs and EDR data for suspicious requests and Java child processes.
- Do not send a command-execution or time-delay payload to production when version evidence already establishes exposure.
Is removing gt-complex a complete fix?
- It removes the vulnerable component from the affected deployment and was documented as an official workaround.
- It can break required functionality or prevent startup.
- Known dependencies include App-Schema, CSW, MongoDB Data Store, OGC API modules, Features Templating, Smart Data Loader, and SOLR Data Store.
- The official dependency list may not cover every extension.
- A full upgrade is preferable.
- Removing the JAR does not investigate or remove an existing compromise. (جيثب)
What evidence suggests a GeoServer host was compromised?
- Java spawned a shell, scripting engine, downloader, or reconnaissance utility.
- New JSP, WAR, script, or executable files appeared in application directories.
- The GeoServer account created a scheduled task, cron entry, service, or startup item.
- The host contacted new external infrastructure shortly after suspicious OGC requests.
- The server began scanning internal systems or connecting to unrelated management ports.
- Database or cloud credentials accessible to GeoServer were used from an unexpected host.
- EDR detected process injection, web-shell behavior, or malicious file execution.
- Several weak signals occurring on the same timeline can be more meaningful than one isolated request error.
Should a patched but previously exposed server be rebuilt?
- Rebuild when there is credible evidence of successful code execution, persistence, credential theft, or unauthorized file modification.
- Patching alone is not sufficient after confirmed compromise.
- Preserve evidence before rebuilding.
- Rotate every credential the GeoServer process could access.
- Investigate adjacent web, database, identity, and management systems.
- A previously vulnerable server with no retained telemetry may require a risk-based decision. Internet exposure, duration, service privileges, KEV status, and the absence of trustworthy logs all increase the case for rebuilding.
- Use a trusted image and reviewed configuration rather than cloning the potentially compromised host.
How should security teams prioritize CVE-2024-36401 now?
- Priority one: Internet-facing, vulnerable, or version-unknown GeoServer instances.
- Priority one: Instances where Java has spawned shells or downloaders, or where suspicious files and persistence exist.
- Priority one: Instances with access to sensitive databases, cloud credentials, or internal management networks.
- Priority two: Internal vulnerable instances reachable from broad user or server networks.
- Priority two: Disaster-recovery and standby systems that could be activated later.
- Priority three: Isolated lab copies with no sensitive data and no untrusted access, provided a remediation deadline and owner are assigned.
- Do not downgrade the issue solely because the server publishes public data. The value to an attacker may be execution, credentials, compute, and network position rather than the map data itself.
Final assessment
CVE-2024-36401 is a clear example of how a seemingly narrow data-processing feature can become a remote execution boundary. A property name entered GeoServer as data, crossed into GeoTools as an expression, and reached a JXPath context with more capability than the operation required. The durable fix was not a longer blacklist. It was to remove Java function resolution from the evaluation context.
The vulnerability deserves continued attention because exploitation is documented, the affected services are frequently public by design, and the consequences extend beyond the GeoServer process. CISA’s federal agency case showed how an unpatched mapping server could become the start of a wider intrusion rather than an isolated application incident.
Defenders should establish the deployed version and actual library set, restrict unnecessary OGC services, apply a supported upgrade, and validate the result at the file, service, network, and monitoring layers. When host evidence indicates execution or persistence, the task is no longer vulnerability remediation. It is incident response.
Safe validation should produce evidence without reproducing a weaponized attack: confirm assets, components, reachability, controls, logs, remediation, and residual risk. That approach is faster to authorize, easier to reproduce, and more useful to the people responsible for restoring trust.

