紧急预警|GeoServerjsonArrayContainsSQL注入

admin 2026-08-23 04:59:30 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: GeoServer的jsonArrayContains函数存在高危SQL注入漏洞,CVSS评分9.8。攻击者无需认证,仅通过构造WFS/WMS接口的恶意CQL_FILTER参数即可拼接SQL,导致PostGIS空间数据全量泄露。若数据库账号具备高权限,可利用COPYTOPROGRAM直接实现RCE。该漏洞影响2.27.0至3.0.0版本,PoC已公开且遭全网扫描。建议立即将GeoServer升级至3.0.1等安全版本,短期内可通过防火墙限制8080端口访问、部署WAF规则拦截恶意参数、以及撤销PostgreSQL账号的superuser与执行程序权限来缩减攻击面,并全面排查日志。 综合评分: 96 文章分类: 漏洞预警,漏洞分析,应急响应,WEB安全,数据安全


cover_image

紧急预警|GeoServer jsonArrayContains SQL注入

撅人

2026年8月18日 00:00 广东

在小说阅读器读本章

去阅读

🔴 导语 · 紧急预警

搞 GIS 的、政务/智慧城市项目的运维和安全兄弟请注意!⚠️

一个 CQL_FILTER 参数就能打穿你的 GeoServer。 不需要登录,不需要认证——攻击者只要能访问到你暴露在外的 WFS/WMS 接口,在 URL 里塞一个恶意 CQL 过滤表达式,jsonArrayContains 函数就会把它原封不动拼进 SQL,数据库里的数据全部带走。如果数据库连接用的是高权限账号,直接 COPY TO PROGRAM 弹 shell,服务器当场失陷

8月12日披露,8月13日 PoC 就公开了,8月14日补丁才出。披露后数小时内就有人开始全网扫描。还在裸奔的赶紧升


🔍 漏洞速览

| | | | — | — | | 漏洞编号 | 暂无 CVE (GHSA: mqjf-5f49-2fjh) | | 漏洞类型 | SQL 注入(CWE-89)→ 可链式 RCE | | CVSS 评分 | 9.8(Critical) · v4.0: 9.3 | | 影响产品 | GeoServer + GeoTools(PostGIS 数据源) | | 攻击前提 | 攻击者能访问 WFS/WMS 接口,无需认证 | | 攻击方式 | 构造恶意 CQL_FILTER → jsonArrayContains 拼接 SQL → 注入/弹 shell | | 受影响版本 | GeoServer 2.27.0 – 3.0.0(含) | | 安全版本 | 3.0.1 / 2.28.5 / 2.27.6 | | PoC 情况 | 已公开 (Python 利用脚本,支持 RCE / 盲注 / 数据提取) | | 在野利用 | 披露后数小时即出现全网扫描探测 |


💥 核心危害:GeoServer 一穿,谁遭殃?

这漏洞不挑食——能查数据,能写文件,能弹 shell,一条龙服务。

GeoServer 在企业里通常扮演什么角色?地图发布、空间数据服务、WMS/WFS/WCS 地理信息服务、智慧城市 GIS 底座。它后面连的数据库里,装的是矢量数据、属性表、行政区划、人口分布——全是敏感数据。它一穿,连锁反应是这样的:

🔓 无认证直接注入:攻击者不需要登录 GeoServer,不需要任何账号密码,只要能访问到 WFS/WMS 接口的 HTTP 端口(默认 8080),在 URL 的 CQL_FILTER 参数里塞个恶意表达式就行

📊 数据库裸奔:jsonArrayContains 函数把用户输入直接拼进 SQL,没有参数化、没有转义。攻击者想查什么查什么——空间数据、属性表、用户密码 hash,全部可拖

🚀 高权限直通 RCE:如果 GeoServer 连 PostgreSQL 用的是 superuser 或有 pg_execute_server_program 权限的账号(很多生产部署就是这样配的),一条 COPY TO PROGRAM 直接在服务器上执行系统命令,服务器当场交枪

🌐 公网暴露面巨大:GeoServer 很多部署在公网(为了给地图前端提供 WMS/WFS 服务),Shodan 上一搜一大把。政务/智慧城市/应急项目重灾区

⏱️ PoC 闪电公开:8月12日披露,8月13日 Python PoC 就上了 GitHub Gist,支持 RCE 模式、盲注模式、数据提取三种模式。脚本小子拿來就能用

💬 攻击者成本 ≈ 一个 HTTP 请求 + 一段 CQL 表达式。防御方成本 ≈ 空间数据库全量泄露 + 服务器失陷 + 火线升级。 而且这次是 jsonArrayContains 的老毛病复发——2023 年 CVE-2023-25157 修过一轮,2026 年又回归了。


🧠 漏洞原理(人话版)

先搞清楚几个概念

CQL_FILTER:GeoServer 的 OGC 标准过滤参数,允许客户端通过 URL 传入过滤条件来筛选地图数据。比如 CQL_FILTER=population > 1000000 就是筛人口超过 100 万的区域。

jsonArrayContains:GeoTools 提供的一个 CQL 过滤函数,用于检查 JSON/JSONB 字段中是否包含某个值。底层调用 PostgreSQL 的 jsonb_path_exists() 函数。

FilterToSqlHelper:GeoTools 里负责把 CQL 过滤表达式翻译成 SQL 的类。漏洞就出在这里。

漏洞本质

GeoTools 的 FilterToSqlHelper.constructEquality() 方法在把 jsonArrayContains 翻译成 SQL 时,用 String.format() 把用户输入直接拼进了 SQL 字符串

// 漏洞代码:value 参数直接拼接,零转义

String sql = String.format(

    “jsonb_path_exists(%s::jsonb, ‘$ ? (@.%s == \”%s\”)’)”,

    column, path, value  // ← value 是攻击者可控的!

);

正常请求:jsonArrayContains("data","/x","y") → 生成正常的 JSONPath 查询。

恶意请求:jsonArrayContains("data","/x","y') ; COPY (SELECT 1) TO PROGRAM 'id' --") → 单引号闭合字符串 → 分号结束原 SQL → 注入 COPY TO PROGRAM 执行系统命令 → 注释符 — 吃掉尾部语法。

为什么用 String.format 而不是 PreparedStatement?

PostgreSQL 的 jsonb_path_exists() 函数的第二个参数是 JSONPath 表达式字符串,不支持绑定参数。GeoTools 的开发者为了绕过这个限制,用 String.format() 手动拼接——但忘记对用户输入做转义。这是一个典型的“绕过框架限制时引入安全漏洞”的案例。

🚨 攻击流程 3 步走

第 1 步:找到目标 GeoServer

攻击者通过 Shodan/FOFA 搜索暴露在公网的 GeoServer 实例(特征:/geoserver/web/ 路径),或者在内网横向时发现 8080 端口跑着 GeoServer。不需要登录,WFS GetFeature 接口默认开放。

第 2 步:构造恶意 CQL_FILTER

向 WFS 接口发送一个带 jsonArrayContains 的 CQL_FILTER,value 参数里塞入 SQL 注入 payload。通过单引号闭合 JSONPath 字符串,分号截断原 SQL,注入任意 SQL 语句。

第 3 步:按需选择攻击模式

如果数据库用户是 superuser → COPY TO PROGRAM 直接弹 shell,RCE 完成。如果不是 → 走盲注路径,用 pg_sleep 做时间盲注,或者用错误回显逐字节提取数据。PoC 脚本三种模式全支持。

🔍 为什么 WFS 1.0 最容易被利用?

WFS 1.0 的响应不需要 numberMatched 字段,所以 GeoServer 生成的 SQL 更简单——过滤条件直接在顶层 WHERE 子句里,攻击者注入的分号能截断整条 SQL 语句并追加堆叠查询。

WFS 2.0 则把过滤条件包在 SELECT count(*) FROM (SELECT ... WHERE [filter]) alias 的子查询里,分号到不了顶层,堆叠查询 RCE 链断了——但盲注和数据提取仍然可行。

⚠️ 2023 年的老漏洞又回来了

2023 年 CVE-2023-25157 / CVE-2023-25158 就修过一轮 OGC Filter SQL 注入,当时 jsonArrayContains 也中招了。当时的缓解措施是开启 preparedStatements 和禁用 encode functions

但 2026 年这次的漏洞是 jsonArrayContains 的回归——之前的修复不完整,preparedStatements 开着也没用,因为 String.format() 根本不走预编译路径。你以为修了的,它又回来了。


⏱️ 3 秒自查

❌ 受影响版本(红区)

• GeoServer 2.27.0 – 3.0.0(含),且使用 PostGIS 数据源

• GeoTools gt-jdbc-postgis:33.1+ / 34.0+ / 35.0

• 前提条件:PostGIS 12+,且有 String 或 JSON 类型的字段

✅ 安全版本(绿区)

• GeoServer 3.0.1(稳定版,GeoTools 35.1)

• GeoServer 2.28.5(维护版,GeoTools 34.5)

• GeoServer 2.27.6(安全修复版,GeoTools 33.6)

自查命令:

1. 查 GeoServer 版本(Web 控制台)

curl -s http://你的GeoServer地址:8080/geoserver/web/wicket/bookmarkable/org.geoserver.web.AboutGeoServerPage | grep -oE “GeoServer [0-9]+.[0-9]+.[0-9]+”

或者直接看 About 页面

curl -s http://你的GeoServer地址:8080/geoserver/web/ | grep -i version

2. 查是否使用了 PostGIS 数据源

登录 GeoServer Web 管理界面 → Stores → 看有没有 PostGIS 类型的数据存储

grep -r “PostGIS” $GEOSERVER_DATA_DIR/workspaces/*/datastores/*/datastore.xml

如果没有 PostGIS 数据源 → 不受此漏洞影响

如果有 → 继续检查数据库连接账号权限

3. 查 PostgreSQL 数据库连接账号权限(关键!)

psql -U geoserver_user -d your_db -c “\du geoserver_user”

如果看到 superuser → 🔴 高危!RCE 一发入魂

如果有 pg_execute_server_program → 🔴 高危!COPY TO PROGRAM 可用

如果只是普通用户 → 🟡 中危!不能 RCE 但数据可被拖走

4. 查 GeoServer 访问日志有没有被攻击痕迹

grep “jsonArrayContains” $GEOSERVER_DATA_DIR/logs/geoserver.log

查 Web 服务器访问日志中的恶意 CQL_FILTER

grep -E “jsonArrayContains|COPY.*PROGRAM|pg_sleep|pg_read_file” /var/log/nginx/access.log

有命中 → 可能已经被打过了,赶紧排查数据泄露


🛡️ 修复方案

✅ 方案一:升级版本(推荐,根治)

补丁已于 8 月 14 日发布,根据当前版本选择对应安全版本:

| | | | — | — | | 当前版本 | 升级目标 | | 3.0.0 | 3.0.1 (稳定版) | | 2.28.x | 2.28.5 (维护版) | | 2.27.x | 2.27.6 (安全修复版) | | 低于 2.27 | 先升到 2.27.6,或直接升 3.0.1 |

停服(如果用 Tomcat 部署)

$CATALINA_HOME/bin/shutdown.sh

备份

cp -r $GEOSERVER_DATA_DIR $GEOSERVER_DATA_DIR.bak

替换 geoserver.war 或二进制包后启动

$CATALINA_HOME/bin/startup.sh

Docker 部署的话直接换镜像 tag

docker pull kartoza/geoserver:3.0.1

官方公告:geoserver.org/announcements/vulnerability/2026/08/14/…

⚠️ 方案二:临时缓解——端口收口 + WAF(立刻执行)

如果暂时无法升级,必须立刻掐断攻击面。核心思路:不让攻击者碰到 WFS/WMS 接口

1. 安全组 / 防火墙硬刚:只允许可信来源访问 GeoServer 端口

iptables -A INPUT -p tcp –dport 8080 -s 10.0.0.0/8 -j ACCEPT

iptables -A INPUT -p tcp –dport 8080 -j DROP

2. Nginx 层拦截恶意 CQL_FILTER(WAF 规则)

if ($args ~* “jsonArrayContains”) { return 403; }

if ($args ~* “(COPY|PROGRAM|pg_sleep|pg_read_file)”) { return 403; }

3. 如果业务不需要 CQL 过滤功能,在 GeoServer 中关闭

编辑 geoserver/data/security/rest.properties,限制 /rest 接口访问

⚠️ WAF 规则可能被绕过(编码变形、大小写混淆等),不能根治。最终还是要升级。

🛡️ 方案三:数据库降权(减少爆炸半径)

如果注入已经发生或无法立即升级,至少把数据库连接账号的权限降到最低——不能 RCE,只丢数据

1. 撤销 superuser 权限

ALTER ROLE geoserver_user NOSUPERUSER;

2. 撤销 pg_execute_server_program(关键!阻断 RCE 链)

ALTER ROLE geoserver_user NOSUPERUSER;

REVOKE pg_execute_server_program FROM geoserver_user;

3. 只授予业务所需的表级权限

GRANT SELECT, INSERT, UPDATE ON geoserver_tables TO geoserver_user;

4. 在 GeoServer PostGIS 数据源设置中禁用 encode functions

Web UI → Stores → 编辑 PostGIS Store → 取消勾选 “Encode functions”

💡 降权后即使被注入,攻击者也只能查数据,不能执行系统命令。但数据泄露风险仍然存在——升级才是正道

🕵️ 入侵排查清单

SQL 注入漏洞不像 RCE 那样留明显后门,但你要确认:

☐ 查 GeoServer 日志和 Nginx 访问日志,有没有包含 jsonArrayContains 的异常 CQL_FILTER 请求

☐ 查有没有 COPY、PROGRAM、pg_sleep、pg_read_file 等 SQL 关键字出现在请求参数中

☐ 查 PostgreSQL 日志有没有异常的 SQL 执行记录(COPY TO PROGRAM、大量 SELECT 查询)

☐ 查 GeoServer 部署目录下有没有新上传的 JSP/PHP 文件(可能通过 COPY TO PROGRAM 写了 Webshell)

☐ 查 PostgreSQL 中是否有新增的用户、权限变更记录、或异常的数据导出操作

☐ 确认攻击窗口期内有没有敏感空间数据被批量查询(对比日常查询量基线)

☐ 升级后做一轮 WFS/WMS 功能端到端验证,确保地图服务正常

☐ 如果确认被攻击过,轮换数据库密码、检查是否有持久化后门


⚠️ 安全提醒

这个漏洞最让人头疼的地方不是它有多复杂——它太简单了

一个 HTTP GET 请求,URL 里塞个 CQL_FILTER,连密码都不用输。PoC 脚本已经公开,支持 RCE、盲注、数据提取三种模式,脚本小子拿来就能跑。披露后几个小时就有人开始全网扫——GeoServer 部署在公网的,大概率已经被探测过了。

更扎心的是,这是 jsonArrayContains 的第二次翻车。2023 年 CVE-2023-25157 修过一轮,当时建议开启 preparedStatements 来防护。结果 2026 年这次回归漏洞,preparedStatements 根本没用——因为漏洞代码走的是 String.format(),不经过预编译路径。你以为修了的,它又回来了,而且之前的缓解措施全部失效。

如果你家的 GeoServer 还跑在公网上,今晚就去查版本、查数据库账号权限。 8080 端口对公网开放的,先关了再说。政务/智慧城市项目的兄弟特别注意——你们是重点靶标。

转发给安全/运维/GIS 团队,别等数据库被拖了才想起来升级。

📎 官方参考

• GeoServer 官方公告:geoserver.org/announcements/vulnerability/2026/08/14/…

• GeoTools GHSA 安全公告:github.com/geotools/geotools/security/advisories/GHSA-mqjf-5f49-2fjh

• Hadrian 技术分析:hadrian.io/blog/here-be-dragons-geoserver-…

• The Hacker News:thehackernews.com/2026/08/unpatched-geoserver-zero-day…

• 奇安信 CERT:secrss.com/index.php/articles/93104

本文仅供安全研究与防御参考,修复请以 GeoServer 官方公告为准。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:撅人 《紧急预警|GeoServer jsonArrayContains SQL注入》

评论:0   参与:  0