r/linuxadmin 15d ago

GeoServer jsonArrayContains unauthenticated SQL injection (GHSA-mqjf-5f49-2fjh) — confirmed regression of CVE-2023-25158, RCE possible on privileged DB roles

Based on the technical breakdown published by Hadrian Security (researcher Melvin Lammerts) and vendor advisories from GeoTools/GeoServer, here's the architectural impact:

**Disclosure timeline:** u/q1uf3ng dropped the vuln on X Aug 12, 10:46 UTC, no CVE at the time. watchTowr told The Hacker News they saw exploitation probes within hours — hundreds of attempts from a small IP pool. GeoServer/GeoTools shipped fixes Aug 14–15 (GeoServer 3.0.1/2.28.5/2.27.6, GeoTools 35.1/34.5/33.6), tracked as GHSA-mqjf-5f49-2fjh, CVSS 9.8.

**Root cause:** jsonArrayContains(<col>,<pointer>,<value>) in GeoTools' PostGIS datastore handling drops <value> straight into a `jsonb_path_exists()` PostgreSQL expression via String.format() — no escaping, no bind param (jsonpath doesn't support bind params in Postgres, which is presumably why someone reached for string formatting here). Reachable pre-auth through public WFS/WMS OGC endpoints via CQL_FILTER.

**Interesting bit for anyone doing exploit dev/detection eng:** the SQL shape differs by GeoServer service. WFS 2.0 wraps the filter in a derived-table count subquery (for numberMatched), which traps a stacked-query semicolon inside the subquery and blocks the obvious RCE route. WFS 1.0 skips that wrapper, landing the injection directly in the top-level WHERE clause — that's the route Hadrian used to reach `COPY ... TO PROGRAM` RCE (confirmed against a local 2.26.1 + PostGIS 15 lab, landed shell as uid=999 postgres).

Without superuser/pg_execute_server_program, injection still works for error-based (CAST AS int) and time-based (pg_sleep) extraction — doesn't need preferQueryMode=simple either, contrary to the commonly cited 2023-era mitigation.

**The regression angle:** GeoTools' own advisory states this is a regression of CVE-2023-25158, and explicitly notes the 2023 mitigation (prepared statements + disabled encode functions) does NOT work against this variant.

Full writeup with detection queries and mitigation checklist: https://www.techgines.com/post/geoserver-jsonarraycontains-sql-injection-ghsa-mqjf-5f49-2fjh (slug pending CMS verification)

We also covered a related unescaped-input-to-SQL-sink pattern in LangGraph's checkpoint storage earlier this year if anyone wants the AI-framework comparison: https://www.techgines.com/post/langchain-langgraph-security-vulnerabilities-expose-enterprise-ai-secrets-three-cves-you-must-patc

**Question for the thread:** for anyone running GeoServer with PostGIS in production — is disabling the "encode functions" option on the datastore (Hadrian's suggested interim mitigation) actually viable for you without breaking existing CQL filter usage, or does that break real filter functionality in your deployments?

4 Upvotes

1 comment sorted by

View all comments

1

u/kernpanic 15d ago

Mostly using it with Oracle, so I think im safe! haha.