CVE-2026-22743
Description
Spring AI's spring-ai-neo4j-store contains a Cypher injection vulnerability in Neo4jVectorFilterExpressionConverter. When a user-controlled string is passed as a filter expression key in Neo4jVectorFilterExpressionConverter of spring-ai-neo4j-store, doKey() embeds the key into a backtick-delimited Cypher property accessor (node.metadata.) after stripping only double quotes, without escaping embedded backticks.This issue affects Spring AI: from 1.0.0 before 1.0.5, from 1.1.0 before 1.1.4.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.springframework.ai:spring-ai-neo4j-storeMaven | >= 1.0.0-M5, < 1.0.5 | 1.0.5 |
org.springframework.ai:spring-ai-neo4j-storeMaven | >= 1.1.0-M1, < 1.1.4 | 1.1.4 |
Affected products
1Patches
13a46c7dd00e4fix: Neo4jVectorFilterExpressionConverter key handling
2 files changed · +36 −2
vector-stores/spring-ai-neo4j-store/src/main/java/org/springframework/ai/vectorstore/neo4j/filter/Neo4jVectorFilterExpressionConverter.java+7 −1 modified@@ -16,6 +16,8 @@ package org.springframework.ai.vectorstore.neo4j.filter; +import org.neo4j.cypherdsl.support.schema_name.SchemaNames; + import org.springframework.ai.vectorstore.filter.Filter; import org.springframework.ai.vectorstore.filter.Filter.Expression; import org.springframework.ai.vectorstore.filter.Filter.Group; @@ -76,7 +78,11 @@ protected void doNot(Expression expression, StringBuilder context) { @Override protected void doKey(Key key, StringBuilder context) { - context.append("node.").append("`metadata.").append(key.key().replace("\"", "")).append("`"); + String sanitized = SchemaNames.sanitize("metadata." + key.key(), true) + .orElseThrow(() -> new IllegalArgumentException( + "Invalid or empty metadata key cannot be used in a Neo4j filter expression: '%s'" + .formatted(key.key()))); + context.append("node.").append(sanitized); } @Override
vector-stores/spring-ai-neo4j-store/src/test/java/org/springframework/ai/vectorstore/neo4j/filter/Neo4jVectorFilterExpressionConverterTests.java+29 −1 modified@@ -126,7 +126,7 @@ public void testDecimal() { @Test public void testComplexIdentifiers() { String vectorExpr = this.converter - .convertExpression(new Expression(EQ, new Key("\"country 1 2 3\""), new Value("BG"))); + .convertExpression(new Expression(EQ, new Key("country 1 2 3"), new Value("BG"))); assertThat(vectorExpr).isEqualTo("node.`metadata.country 1 2 3` = \"BG\""); } @@ -139,6 +139,13 @@ public void testComplexIdentifiers2() { .isEqualTo("node.`metadata.author` IN [\"john\",\"jill\"] AND node.`metadata.article_type` = \"blog\""); } + @Test + public void testComplexIdentifiers3() { + String vectorExpr = this.converter + .convertExpression(new Expression(EQ, new Key("\"country 1 2 3\""), new Value("BG"))); + assertThat(vectorExpr).isEqualTo("node.`metadata.\"country 1 2 3\"` = \"BG\""); + } + @Test public void testEmptyList() { // category IN [] @@ -250,4 +257,25 @@ public void testNegativeNumbers() { assertThat(vectorExpr).isEqualTo("node.`metadata.valueA` <= -5 AND node.`metadata.valueB` >= -10"); } + @Test + public void testKeyWithBacktick() { + String vectorExpr = this.converter + .convertExpression(new Expression(EQ, new Key("a` IS NOT NULL WITH node, score //"), new Value("v"))); + assertThat(vectorExpr).isEqualTo("node.`metadata.a`` IS NOT NULL WITH node, score //` = \"v\""); + } + + @Test + public void testKeyFromTextParser() { + Expression expr = new FilterExpressionTextParser().parse("\"safe_key\" == 'value'"); + String vectorExpr = this.converter.convertExpression(expr); + assertThat(vectorExpr).isEqualTo("node.`metadata.safe_key` = \"value\""); + } + + @Test + public void testKeyWithControlCharacters() { + String vectorExpr = this.converter + .convertExpression(new Expression(EQ, new Key("key\nwith\nnewline"), new Value("v"))); + assertThat(vectorExpr).isEqualTo("node.`metadata.key\nwith\nnewline` = \"v\""); + } + }
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-7cj7-rcw6-p68vghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-22743ghsaADVISORY
- spring.io/security/cve-2026-22743nvdVendor AdvisoryWEB
- github.com/spring-projects/spring-ai/commit/3a46c7dd00e4adc17a132b9438149bde94da244fghsaWEB
- github.com/spring-projects/spring-ai/releases/tag/v1.0.5ghsaWEB
- github.com/spring-projects/spring-ai/releases/tag/v1.1.4ghsaWEB
News mentions
0No linked articles in our index yet.