Skip to content

LangChain4j: SQL injection via metadata filters in langchain4j-mariadb and langchain4j-pgvector

High severity GitHub Reviewed Published Jun 17, 2026 in langchain4j/langchain4j • Updated Jun 17, 2026

Package

maven dev.langchain4j:langchain4j-mariadb (Maven)

Affected versions

<= 1.2.0-beta8
>= 1.3.0-beta9, <= 1.5.0-beta11
>= 1.6.0-beta12, <= 1.11.7-beta19
>= 1.12.1-beta21, <= 1.16.2-beta26

Patched versions

1.2.1-beta8
1.5.1-beta11
1.11.8-beta19
1.16.3-beta26
maven dev.langchain4j:langchain4j-pgvector (Maven)
<= 1.2.0-beta8
>= 1.3.0-beta9, <= 1.5.0-beta11
>= 1.6.0-beta12, <= 1.11.7-beta19
>= 1.12.1-beta21, <= 1.16.2-beta26
1.2.1-beta8
1.5.1-beta11
1.11.8-beta19
1.16.3-beta26

Description

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 fell back to the raw,
unescaped key when the driver could not quote it as an identifier (e.g. a
character).

The filter key is the runtime injection surface; both stores' search() (including pgvector's
HYBRID mode) and removeAll(Filter) are affected. Add/upsert operations a
parameterized and not affected.

Impact

Applications that allow attacker-influenced metadata filter keys (e.g. use
LLM-generated filters) to reach these stores are exposed to SQL injection: blind data
exfiltration, denial of service via sleep functions, and — through `remove
deletion of arbitrary rows. Applications using only hard-coded, developer-defined filter keys
are not reachable.

Patches

Fixed in langchain4j-mariadb and langchain4j-pgvector 1.16.3-beta26:

  • JSON filter keys are escaped before being embedded in the SQL string lit
    quotes doubled, correct for PostgreSQL standard_conforming_strings = on; MariaDB: backslash
    and single quote).
  • MariaDB string values escape both \ and '.
  • Column-mode keys are validated/quoted as identifiers and rejected when u
    concatenated as raw SQL.

Workarounds

  • Do not pass untrusted input as metadata filter keys.
  • Restrict filter keys to a known allow-list at the application layer.

References

  • pgvector: JSONFilterMapper, ColumnFilterMapper
  • MariaDB: JSONFilterMapper, MariaDbFilterMapper, ColumnFilterMapper

References

@dliubarskyi dliubarskyi published to langchain4j/langchain4j Jun 17, 2026
Published to the GitHub Advisory Database Jun 17, 2026
Reviewed Jun 17, 2026
Last updated Jun 17, 2026

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
Low
User interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
Low
Availability
Low

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L

EPSS score

Weaknesses

Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')

The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data. Learn more on MITRE.

CVE ID

CVE-2026-55405

GHSA ID

GHSA-2mfg-cc43-9pcj

Credits

Loading Checking history
See something to contribute? Suggest improvements for this vulnerability.