← Back to Feed CACHED · 2026-10-14 03:13:49 · CACHE_KEY CVE-2024-36401
CVE-2024-36401 · CWE-95 · Disclosed 2024-07-01

GeoServer OGC Filter / Property Name XPath Evaluation Remote Code Execution

ASSESSED — NOISGATE
Vendor
—
—
—
Reassessed
—
—
—
Verdict: —
Do you agree?
01 · The Real Story

Like leaving a loaded terminal open on the internet with a sign that says 'type anything'

CVE-2024-36401 is an unauthenticated remote code execution flaw in GeoServer (all versions before 2.22.6, 2.23.x before 2.23.6, 2.24.x before 2.24.4, and 2.25.x before 2.25.2) caused by the GeoTools library unsafely passing OGC request property names to the Apache Commons JXPath evaluator. An attacker sends a single HTTP request — through WFS GetPropertyValue, WFS GetFeature, WMS GetMap, WMS GetFeatureInfo, WMS GetLegendGraphic, or WPS Execute endpoints — containing a malicious XPath expression that calls java.lang.Runtime.getRuntime().exec(). No credentials, no special headers, no prior access — just one crafted GET or POST against any default GeoServer installation and you own the process.

The vendor CVSS of 9.8 CRITICAL is dead accurate — arguably conservative. The attack requires zero authentication, zero user interaction, targets a default installation, and has been weaponized into a Metasploit module, multiple GitHub PoCs, a Nuclei template, and at least six distinct malware campaigns including APT41's SideWalk backdoor. CISA confirmed a U.S. federal agency was compromised through an unpatched public-facing GeoServer. Over 7,100 instances remain internet-exposed. This is the textbook case where vendor severity matches reality perfectly.

"Unauthenticated RCE in default GeoServer installs, mass-exploited by botnets and APTs — patch now."
02 · The Attack Path

5 steps from start to impact.

STEP 01

Discover exposed GeoServer

Attacker scans the internet for GeoServer instances using Shodan, Censys, FOFA, or simple Google dorks (inurl:/geoserver/web). As of mid-2025, roughly 7,100 instances were publicly reachable across 99 countries. The default GeoServer web interface and OWS endpoints are trivially fingerprinted via HTTP response headers and the /geoserver/web/ login page.
Conditions required:
  • Target GeoServer must be network-reachable (internet-facing or attacker on same network)
Where this breaks in practice:
  • GeoServer behind a reverse proxy or VPN is not directly reachable — but most GIS portals are public by design
Detection/coverage: Shodan/Censys/FOFA queries; Censys ASM has a built-in risk rule for CVE-2024-36401
STEP 02

Send malicious OGC request

Attacker crafts an HTTP GET or POST request to any of six OGC endpoints (e.g., /geoserver/ows?service=WFS&version=2.0.0&request=GetPropertyValue&typeNames=<layer>&valueReference=exec(java.lang.Runtime.getRuntime(),'<cmd>')) embedding arbitrary Java method calls in the valueReference or CQL_FILTER parameter. No authentication is required. The request is indistinguishable from normal OGC traffic at a protocol level without deep payload inspection.
Conditions required:
  • GeoServer version is vulnerable (pre-2.22.6 / pre-2.23.6 / pre-2.24.4 / pre-2.25.2)
  • At least one published feature type exists (default in any configured GeoServer)
Where this breaks in practice:
  • WAF with deep XPath/OGC inspection rules could block the payload — but almost no WAFs ship with GeoServer-specific rules out of the box
Detection/coverage: Nuclei template CVE-2024-36401; Metasploit module exploit/multi/http/geoserver_unauth_rce_cve_2024_36401; Acunetix and Tenable plugins available
STEP 03

GeoTools evaluates XPath → code execution

The GeoTools library passes the attacker-controlled property name string to Apache Commons JXPath for evaluation. JXPath interprets it as a live XPath expression, resolving Java method references and executing them in the JVM context of the GeoServer process. The attacker achieves arbitrary command execution under the service account running GeoServer (often root in Docker deployments, or a dedicated service account on bare metal).
Conditions required:
  • The gt-complex-x.y.jar library is present (it is in every default installation)
Where this breaks in practice:
  • Removing gt-complex-x.y.jar breaks Application Schema, CSW, and MongoDB Data Store extensions — organizations using those features face a functionality trade-off
Detection/coverage: EDR/HIDS should flag unexpected child processes spawned by the Java/Tomcat process
STEP 04

Post-exploitation: reverse shell or malware drop

Observed campaigns deploy GOREVERSE reverse proxies, APT41's SideWalk Linux backdoor (ChaCha20-encrypted C2), JenX/Mirai-variant botnets, Condi DDoS bots, and XMRig coinminers. The attacker typically downloads a second-stage payload via curl or wget from an attacker-controlled server, then establishes persistent C2. In the CISA-documented federal agency incident, attackers maintained access for approximately three weeks before endpoint detection fired.
Conditions required:
  • Outbound network access from the GeoServer host (HTTP/HTTPS or raw TCP to C2)
Where this breaks in practice:
  • Egress filtering or network segmentation can block the download/callback — but GeoServer hosts often need outbound access for tile fetching and WMS cascading
Detection/coverage: GreyNoise tags for GeoServer exploitation; network IDS signatures for GOREVERSE, SideWalk C2 patterns; EDR alerting on shell spawned by Java process
STEP 05

Lateral movement and data access

Once on the GeoServer host, the attacker pivots into the internal network. GeoServer configurations frequently contain database credentials (PostGIS, Oracle Spatial, SQL Server) in datastore.xml files, granting direct access to backend geospatial databases. In government and critical infrastructure deployments, these databases may contain sensitive location data, infrastructure mapping, or classified geospatial intelligence.
Conditions required:
  • GeoServer host has network adjacency to internal resources
  • Database credentials stored in GeoServer configuration
Where this breaks in practice:
  • Network microsegmentation limits lateral movement — but GeoServer must reach its backing data stores by design
Detection/coverage: Database audit logging; anomalous query patterns from the GeoServer service account; lateral movement detection in NDR/XDR
03 · Compensating Control

1
CRITICAL 9.8→IGNORE 0.0
SEVERITY REDUCED
Patch to GeoServer ≥ 2.23.6 / 2.24.4 / 2.25.2 immediately — The only complete remediation. Given CRITICAL severity and active exploitation, deploy within 3 days per noisgate mitigation SLA. The KEV due date (2024-08-05) has already passed — every day unpatched is active risk acceptance. Test in a staging GIS environment first, but do not let testing delay production patching beyond 72 hours.
2
CRITICAL 9.8→IGNORE 0.0
SEVERITY REDUCED
Remove gt-complex-x.y.jar as an emergency workaround — If patching is blocked (e.g., custom GeoTools extensions need regression testing), delete gt-complex-*.jar from the GeoServer WEB-INF/lib/ directory and restart. This eliminates the vulnerable JXPath evaluation path. Deploy within hours if patching cannot happen in 3 days. Caveat: breaks Application Schema, CSW, and MongoDB Data Store extensions.
3
CRITICAL 9.8→HIGH 7.5
SEVERITY REDUCED
Place GeoServer behind a reverse proxy with OGC request filtering — Deploy a WAF or reverse proxy (e.g., ModSecurity, NGINX with lua-resty-waf) with rules that inspect valueReference, CQL_FILTER, and SLD_BODY parameters for Java class references (java.lang.Runtime, exec(, getRuntime). This is defense-in-depth, not a substitute for patching — sophisticated encodings can bypass string-matching rules. Deploy within 3 days.
4
CRITICAL 9.8→MEDIUM 5.5
SEVERITY REDUCED
Restrict GeoServer network exposure via VPN or IP allowlisting — If the GeoServer does not need to serve the general public, move it behind a VPN or restrict inbound access to known IP ranges at the firewall/security group level. This eliminates the unauthenticated-remote attack vector for opportunistic scanners and botnets. Deploy within 3 days.
5
CRITICAL 9.8→HIGH 8.0
SEVERITY REDUCED
Enable egress filtering and network segmentation — Block outbound connections from the GeoServer host except to known tile sources, WMS cascading targets, and backing databases. This prevents the attacker from downloading second-stage payloads or establishing C2 even if RCE is achieved. Segment the GeoServer host from internal networks to limit lateral movement.
What doesn't work
  • Authentication on the GeoServer web admin console — the vulnerability is in the OWS/OGC service endpoints (WFS, WMS, WPS), not the admin UI. Securing the admin login does nothing to block exploitation.
  • Disabling the GeoServer web admin interface — the OGC service endpoints remain active and exploitable regardless of whether the web UI is enabled.
  • Java SecurityManager — GeoServer deprecated SecurityManager support in modern versions, and commons-jxpath's eval path bypasses typical SecurityManager policies in practice.
  • Rate limiting — a single request achieves RCE; rate limiting cannot stop a one-shot exploit.
04 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationConfirmed and widespread. CISA KEV-listed 2024-07-15; CISA published incident response lessons from a compromised U.S. federal agency (Sept 2025). FortiGuard Labs documented campaigns deploying SideWalk (APT41-linked), GOREVERSE, JenX/Mirai, Condi botnet, and multiple XMRig coinminer variants. As of Aug 2025, attacks involving PolarEdge and Gayfemboy botnets also leverage this CVE to monetize ~7,100 exposed instances.
PoC / exploit availabilitySaturated. Metasploit module: exploit/multi/http/geoserver_unauth_rce_cve_2024_36401 (by h00die-gr3y). Nuclei template: CVE-2024-36401.yaml. GitHub PoCs: bigb0x/CVE-2024-36401, daniellowrie/CVE-2024-36401-PoC, y1s4s/CVE-2024-36401-PoC. Acunetix and Tenable Nessus (plugin 204972) have detection checks.
EPSS score0.99813 (100th percentile) — top of the scale; near-certainty of exploitation activity
KEV statusAdded 2024-07-15, due date 2024-08-05. BOD 22-01 remediation deadline has long passed.
CVSS vector interpretationCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H — Network-reachable, low complexity, no privileges, no user interaction, full CIA impact. Every sub-metric is at worst-case. CVSS 4.0 vector scores 9.3 with /E:A (active exploitation).
Affected versionsGeoServer < 2.22.6, 2.23.0–2.23.5, 2.24.0–2.24.3, 2.25.0–2.25.1. Underlying flaw is in GeoTools gt-complex library — any application embedding GeoTools with JXPath evaluation is potentially affected.
Fixed versions2.22.6, 2.23.6, 2.24.4, 2.25.2. Workaround: remove gt-complex-x.y.jar (breaks Application Schema, CSW, MongoDB extensions).
Exposure dataShadowserver/Censys identified ~6,600 exposed instances (July 2024); by Aug 2025 the count rose to ~7,100 across 99 countries with highest concentrations in the U.S., China, and Germany. Many are government GIS portals designed to be public-facing.
Disclosure date2024-06-30 (GitHub Security Advisory GHSA-6jj6-gm7p-fcvv); NVD published 2024-07-01.
Reporting researcherSteve Ikeoka (GitHub: sikeoka), coordinated by Jody Garnett (jodygarnett), with Andrea Aime (aaime) credited for additional contribution.

Sources.

  1. GitHub Security Advisory GHSA-6jj6-gm7p-fcvv
  2. NVD — CVE-2024-36401
  3. CISA KEV Entry (July 15, 2024)
  4. FortiGuard Labs — Threat Actors Exploit GeoServer CVE-2024-36401
  5. GeoServer Official Vulnerability Advisory
  6. The Hacker News — GeoServer Exploits, PolarEdge, and Gayfemboy Botnets
  7. Nuclei Template — CVE-2024-36401.yaml
  8. Metasploit Module — GeoServer Unauth RCE
05 · The Call

Final Verdict
= UNCHANGED to CRITICAL (9.8/10)

Why this verdict

  • Zero authentication friction: The attack requires no credentials, no session, no API key — a single HTTP request to a default endpoint achieves RCE. This is the lowest possible attacker effort for the highest possible impact.
  • Zero configuration friction: Every default GeoServer installation is vulnerable. There is no 'secure by default' configuration that must be weakened. The vulnerable code path is exercised by normal OGC service requests.
  • Exploit maturity is maximum: Metasploit module, Nuclei template, and at least three public GitHub PoCs reduce the attacker skill requirement to script-kiddie level. The EPSS score of 0.99813 reflects near-universal exploitability.
  • Active mass exploitation confirmed: CISA KEV-listed with documented federal agency compromise. At least six distinct malware families (SideWalk/APT41, GOREVERSE, JenX, Condi, PolarEdge, Gayfemboy) actively target this CVE. This is not theoretical — it is being industrially exploited.
  • Role multiplier: GeoServer is canonically deployed as a public-facing geospatial service by government agencies, critical infrastructure operators, utilities, and defense organizations. The CISA-documented incident confirms federal agency compromise. While GeoServer is not itself an IdP or hypervisor, its deployment role in government and CI environments means compromise yields access to sensitive geospatial data and a foothold in high-value networks. With ~7,100 internet-exposed instances across 99 countries and confirmed government targets, the blast radius is host → network → potentially sensitive data/infrastructure. The floor is CRITICAL because the component is internet-facing by design and the chain is frictionless.
  • No friction adjustments warranted: Unlike vulns requiring authentication, internal network position, or non-default configuration, every prerequisite for this chain is met by the default deployment model. There is no compounding downward pressure.

Why not higher?

A 9.8 is already at the ceiling of CVSS 3.1 for Scope:Unchanged. The only way to reach 10.0 would be Scope:Changed, which would require the vulnerability to directly impact resources beyond the GeoServer host's security scope. While post-exploitation pivot is devastating, the initial RCE is scoped to the GeoServer process — the vendor's 9.8 is the correct maximum.

Why not lower?

Every friction-reducing factor is absent: no auth required, no user interaction, default config vulnerable, trivial exploit complexity, massive PoC availability, and confirmed mass exploitation by nation-state and criminal actors. Downgrading this CVE would require evidence that the attack chain has meaningful friction — it does not. The KEV listing, EPSS at 99th percentile, and CISA incident response engagement all independently confirm CRITICAL is the floor.

06 · Verification

Crowdsourced verification payload.

Run this script on the GeoServer host as the user who manages the GeoServer installation (or root). It checks the installed GeoServer version from web.xml and the presence of the vulnerable gt-complex JAR. Example: chmod +x check_cve_2024_36401.sh && sudo ./check_cve_2024_36401.sh /opt/geoserver

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_cve_2024_36401.sh — Detect CVE-2024-36401 in GeoServer installations
# Usage: ./check_cve_2024_36401.sh <GEOSERVER_HOME>
# Exit codes: 1=VULNERABLE, 0=PATCHED, 2=UNKNOWN

set -euo pipefail

GS_HOME="${1:-/opt/geoserver}"
WEBAPP="$GS_HOME/webapps/geoserver"
RESULT="UNKNOWN"

if [ ! -d "$WEBAPP" ] && [ -d "$GS_HOME/data" ]; then
  # Try common alternative layouts
  for candidate in "$GS_HOME" "$GS_HOME/webapps/geoserver" /var/lib/tomcat*/webapps/geoserver /usr/share/geoserver/webapps/geoserver; do
    [ -d "$candidate/WEB-INF" ] && WEBAPP="$candidate" && break
  done
fi

if [ ! -d "$WEBAPP/WEB-INF" ]; then
  echo "[!] Cannot find GeoServer webapp directory. Tried: $WEBAPP"
  echo "UNKNOWN"
  exit 2
fi

# Extract version from manifest or version file
VERSION=""
if [ -f "$WEBAPP/WEB-INF/classes/GeoServerApplication.properties" ]; then
  VERSION=$(grep -oP 'version=\K[0-9.]+' "$WEBAPP/WEB-INF/classes/GeoServerApplication.properties" 2>/dev/null || true)
fi
if [ -z "$VERSION" ]; then
  VERSION=$(unzip -p "$WEBAPP/WEB-INF/lib/gs-main-"*.jar META-INF/MANIFEST.MF 2>/dev/null | grep -oP 'Implementation-Version: \K[0-9.]+' || true)
fi
if [ -z "$VERSION" ]; then
  VERSION=$(ls "$WEBAPP/WEB-INF/lib/gs-main-"*.jar 2>/dev/null | grep -oP 'gs-main-\K[0-9.]+' || true)
fi

# Check for gt-complex JAR (workaround indicator)
GT_COMPLEX=$(ls "$WEBAPP/WEB-INF/lib/gt-complex-"*.jar 2>/dev/null | head -1 || true)

echo "=== CVE-2024-36401 Check ==="
echo "GeoServer path: $WEBAPP"
echo "Detected version: ${VERSION:-not found}"
echo "gt-complex JAR: ${GT_COMPLEX:-REMOVED (workaround applied)}"
echo ""

if [ -z "$VERSION" ]; then
  echo "[!] Could not determine GeoServer version."
  if [ -z "$GT_COMPLEX" ]; then
    echo "[+] gt-complex JAR has been removed — workaround is in place."
    RESULT="PATCHED"
  else
    RESULT="UNKNOWN"
  fi
else
  # Version comparison
  ver_compare() {
    printf '%s\n' "$1" "$2" | sort -V | head -n1
  }
  MAJOR_MINOR=$(echo "$VERSION" | cut -d. -f1,2)
  case "$MAJOR_MINOR" in
    2.25)
      if [ "$(ver_compare "$VERSION" "2.25.2")" = "$VERSION" ] && [ "$VERSION" != "2.25.2" ]; then
        RESULT="VULNERABLE"
      else
        RESULT="PATCHED"
      fi
      ;;
    2.24)
      if [ "$(ver_compare "$VERSION" "2.24.4")" = "$VERSION" ] && [ "$VERSION" != "2.24.4" ]; then
        RESULT="VULNERABLE"
      else
        RESULT="PATCHED"
      fi
      ;;
    2.23)
      if [ "$(ver_compare "$VERSION" "2.23.6")" = "$VERSION" ] && [ "$VERSION" != "2.23.6" ]; then
        RESULT="VULNERABLE"
      else
        RESULT="PATCHED"
      fi
      ;;
    2.22)
      if [ "$(ver_compare "$VERSION" "2.22.6")" = "$VERSION" ] && [ "$VERSION" != "2.22.6" ]; then
        RESULT="VULNERABLE"
      else
        RESULT="PATCHED"
      fi
      ;;
    *)
      # Versions before 2.22 are all vulnerable
      if [ "$(ver_compare "$VERSION" "2.22.0")" = "$VERSION" ]; then
        RESULT="VULNERABLE"
      else
        # 2.26+ would be patched
        RESULT="PATCHED"
      fi
      ;;
  esac
  # Override if workaround applied
  if [ "$RESULT" = "VULNERABLE" ] && [ -z "$GT_COMPLEX" ]; then
    echo "[*] Vulnerable version detected but gt-complex JAR removed — workaround active."
    RESULT="PATCHED"
  fi
fi

echo ""
echo "$RESULT"
case "$RESULT" in
  VULNERABLE) exit 1 ;;
  PATCHED) exit 0 ;;
  *) exit 2 ;;
esac