LangChain4j: SQL injection via metadata filters in langchain4j-mariadb and langchain4j-pgvector
Date: 2026-06
Affected: maven/dev.langchain4j:langchain4j-pgvector, maven/dev.langchain4j:langchain4j-pgvector, maven/dev.langchain4j:langchain4j-pgvector
Attack vector: sql-injection
Category: vulnerability-disclosure
Severity: High
CVE: CVE-2026-55405
CWE: CWE-89
CVSS: 7.6 (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L)

### Summary The MariaDB and pgvector embedding stores build metadata-filter SQL by string-concatenating filter **keys** (and, in MariaDB, string **values**) directly into the query without adequate escaping. A crafted metadata key in `EmbeddingSearchRequest.filter()` can break out of its SQL context and inject arbitrary SQL into the statements executed by the stores' search and `removeAll(Filter)` operations. ### Details **pgvector — JSON mode (default, `COMBINED_JSON` / `COMBINED_JSONB`).** `JSONFilterMapper` places the key inside a single-quoted SQL literal (the JSON key of the `->>` operator) with no escaping: (metadata->>'<key>')::text A key containing a single quote breaks out, e.g. `metadataKey("')::text IS NOT NULL OR pg_sleep(1) IS NOT NULL --")` injects a live `pg_sleep(1)` (observable as a delay; exploitable for blind data extraction). **pgvector — column mode (`COLUMN_PER_KEY`).** `ColumnFilterMapper` used the key as a bare, unquoted, unvalidated SQL identifier (`<key>::<type>`), so a key such as `1=1 OR true --` injects directly. **MariaDB — JSON mode (default).** `JSONFilterMapper` placed the key inside the JSON path literal `'$.<key>'` unescaped (same break-out mechanism). Additionally, `MariaDbFilterMapper.formatValue()` escaped `'` but not `\`; because MariaDB treats backslash as an escape character by default, a string value ending in a backslash could also break out of its literal. **MariaDB — column mode (`COLUMN_PER_KEY`).** `ColumnFilterMapper`


Mitigations:

Architectural layers (MAESTRO):