Every CVE Search/ Get API key

CVE-2026-55615

Langroid: Neo4jChatAgent executes LLM-generated Cypher without validation (prompt-to-Cypher injection; config-conditional RCE), mirroring the SQLChatAgent bug fixed in CVE-2026-25879

9.2 CriticalFix available

Langroid is a framework for building large-language-model-powered applications. Prior to version 0.65.5, Neo4jChatAgent passes LLM-generated Cypher queries straight to the Neo4j driver with no validation, no statement-type allowlist, and no opt-out gate. The query text is influenceable by prompt injection (direct user input or indirect content the agent reads back via RAG), so an attacker who can influence the prompt can read or destroy all graph data and, when APOC or dbms.security procedures are enabled on the server, achieve OS-command and filesystem access. This is the same defect class and threat model as the SQLChatAgent prompt-to-SQL-to-RCE issue fixed in version 0.63.0 (CVE-2026-25879); that fix did not extend to the neo4j module. Version 0.65.5 contains a fix for the neo4j module.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
High

Exploit likelihood

0.46%Unchanged since Jul 10, 2026
90%50%10%1%

What each source reports

CVE List Score used 9.2

Langroid: Neo4jChatAgent executes LLM-generated Cypher without validation (prompt-to-Cypher injection; config-conditional RCE), mirroring the SQLChatAgent bug fixed in CVE-2026-25879

Langroid is a framework for building large-language-model-powered applications. Prior to version 0.65.5, Neo4jChatAgent passes LLM-generated Cypher queries straight to the Neo4j driver with no validation, no statement-type allowlist, and no opt-out gate. The query text is influenceable by prompt injection (direct user input or indirect content the agent reads back via RAG), so an attacker who can influence the prompt can read or destroy all graph data and, when APOC or dbms.security procedures are enabled on the server, achieve OS-command and filesystem access. This is the same defect class and threat model as the SQLChatAgent prompt-to-SQL-to-RCE issue fixed in version 0.63.0 (CVE-2026-25879); that fix did not extend to the neo4j module. Version 0.65.5 contains a fix for the neo4j module.

Record
CVE-2026-55615
CVSS 4.0
9.2 CriticalCVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Weakness
CWE-74
Updated
2026-11-02
EUVDEUVD-2026-42761 9.2

Langroid is a framework for building large-language-model-powered applications. Prior to version 0.65.5, Neo4jChatAgent passes LLM-generated Cypher queries straight to the Neo4j driver with no validation, no statement-type allowlist, and no opt-out gate. The query text is influenceable by prompt injection (direct user input or indirect content the agent reads back via RAG), so an attacker who can influence the prompt can read or destroy all graph data and, when APOC or dbms.security procedures are enabled on the server, achieve OS-command and filesystem access. This is the same defect class and threat model as the SQLChatAgent prompt-to-SQL-to-RCE issue fixed in version 0.63.0 (CVE-2026-25879); that fix did not extend to the neo4j module. Version 0.65.5 contains a fix for the neo4j module.

Record
EUVD-2026-42761
CVSS 4.0
9.2 CriticalCVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-2pq5-3q89-j7cc 9.2

Langroid: Neo4jChatAgent executes LLM-generated Cypher without validation (prompt-to-Cypher injection; config-conditional RCE), mirroring the SQLChatAgent bug fixed in CVE-2026-25879

Neo4jChatAgent passes LLM-generated Cypher queries straight to the Neo4j driver with no validation, no statement-type allowlist, and no opt-out gate. The query text is influenceable by prompt injection (direct user input or indirect content the agent reads back via RAG), so an attacker who can influence the prompt can read or destroy all graph data and, when APOC or dbms.security procedures are enabled on the server, achieve OS-command and filesystem access. This is the same defect class and threat model as the SQLChatAgent prompt-to-SQL-to-RCE issue fixed in version 0.63.0 (CVE-2026-25879); that fix did not extend to the neo4j module.

Technical detail

Untrusted-input to sink trace (reviewed on langroid HEAD b9df06f, v0.65.3):

  1. Tool schemas accept raw query text from the LLM. langroid/agent/special/neo4j/tools.py:4-9 (CypherRetrievalTool.cypher_query: str) and :15-21 (CypherCreationTool.cypher_query: str). These tools are enabled unconditionally in neo4j_chat_agent.py:412-419 (enable_message([GraphSchemaTool, CypherRetrievalTool, CypherCreationTool, DoneTool])).

  2. Read path. neo4j_chat_agent.py:300 cypher_retrieval_tool(msg) -> :325 query = msg.cypher_query -> :328 self.read_query(query) -> :223 session.run(query, parameters). The LLM-controlled string is the first positional argument to session.run; parameters is None. No validation occurs between :325 and :223.

  3. Write path. neo4j_chat_agent.py:338 cypher_creation_tool(msg) -> :348 query = msg.cypher_query -> :351 self.write_query(query) -> :276 session.write_transaction(lambda tx: tx.run(query, parameters)). The only inspection of the string (write_query :251-264) is a query.upper() substring test for CREATE/MERGE/CONSTRAINT/INDEX whose sole effect is setting self.config.database_created = True; it blocks nothing. A query such as MATCH (n) DETACH DELETE n (the same statement the built-in remove_database helper runs at :287-293) passes unrestricted.

  4. Guarded-sibling contrast proving the incomplete fix. The SQLChatAgent, patched for the parent CVE, validates every query before execution. langroid/agent/special/sql/sql_chat_agent.py:256 defines allow_dangerous_operations: bool = False (opt-in gate); :618 _validate_query runs (a) a dangerous-pattern regex blocklist (_DANGEROUS_SQL_PATTERNS, :628-641), (b) a sqlglot statement-type allowlist defaulting to SELECT-only (:643-686), and (c) an AST-level dangerous-function blocklist (:687-704). run_query calls rejection = self._validate_query(query) at :721 before executing. The neo4j read_query/write_query paths have no equivalent: a grep for _validate_query/allow_dangerous in neo4j_chat_agent.py returns nothing. The defense exists for SQL and is simply absent for Cypher, which is the definition of an incomplete fix for the same prompt-to-query-language injection class.

Proof of concept (static, no third-party systems, no live Neo4j required)

Step 1 (presence vs absence of the guard, one command):

grep -n "_validate_query\|allow_dangerous" langroid/agent/special/sql/sql_chat_agent.py    # SQL: many hits (gate + validator + call site :721)
grep -n "_validate_query\|allow_dangerous" langroid/agent/special/neo4j/neo4j_chat_agent.py # neo4j: ZERO hits

Step 2 (sink trace is direct, no interposed check):

read_query:  msg.cypher_query (line 325) -> read_query(query) (328) -> session.run(query, parameters) (223)
write_query: msg.cypher_query (348) -> write_query(query) (351) -> tx.run(query, parameters) (276)

The only string inspection (write_query 251-264) is a .upper() substring test that only sets database_created=True and rejects nothing. The asymmetry (validator + opt-out gate enforced on every SQL query at sql_chat_agent.py:721; nothing on either Cypher path) is the deterministic artifact: the same project, for the same injection class, guards one query language and not the other. A dynamic confirmation against an operator-owned disposable Neo4j (create a CSPRNG-marked…

Record
GHSA-2pq5-3q89-j7cc
CVSS 4.0
9.2 CriticalCVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Weakness
CWE-74
Updated
2026-11-02
NVD 9.2

Langroid is a framework for building large-language-model-powered applications. Prior to version 0.65.5, Neo4jChatAgent passes LLM-generated Cypher queries straight to the Neo4j driver with no validation, no statement-type allowlist, and no opt-out gate. The query text is influenceable by prompt injection (direct user input or indirect content the agent reads back via RAG), so an attacker who can influence the prompt can read or destroy all graph data and, when APOC or dbms.security procedures are enabled on the server, achieve OS-command and filesystem access. This is the same defect class and threat model as the SQLChatAgent prompt-to-SQL-to-RCE issue fixed in version 0.63.0 (CVE-2026-25879); that fix did not extend to the neo4j module. Version 0.65.5 contains a fix for the neo4j module.

Record
CVE-2026-55615
CVSS 4.0
9.2 CriticalCVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Weakness
CWE-74
Updated
2026-11-02
OSV 9.2

Langroid: Neo4jChatAgent executes LLM-generated Cypher without validation (prompt-to-Cypher injection; config-conditional RCE), mirroring the SQLChatAgent bug fixed in CVE-2026-25879

Langroid is a framework for building large-language-model-powered applications. Prior to version 0.65.5, Neo4jChatAgent passes LLM-generated Cypher queries straight to the Neo4j driver with no validation, no statement-type allowlist, and no opt-out gate. The query text is influenceable by prompt injection (direct user input or indirect content the agent reads back via RAG), so an attacker who can influence the prompt can read or destroy all graph data and, when APOC or dbms.security procedures are enabled on the server, achieve OS-command and filesystem access. This is the same defect class and threat model as the SQLChatAgent prompt-to-SQL-to-RCE issue fixed in version 0.63.0 (CVE-2026-25879); that fix did not extend to the neo4j module. Version 0.65.5 contains a fix for the neo4j module.

Record
CVE-2026-55615
CVSS 4.0
9.2 CriticalCVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Weakness
CWE-74
Updated
2026-11-02
OSVGHSA-2pq5-3q89-j7cc 9.2

Langroid: Neo4jChatAgent executes LLM-generated Cypher without validation (prompt-to-Cypher injection; config-conditional RCE), mirroring the SQLChatAgent bug fixed in CVE-2026-25879

Neo4jChatAgent passes LLM-generated Cypher queries straight to the Neo4j driver with no validation, no statement-type allowlist, and no opt-out gate. The query text is influenceable by prompt injection (direct user input or indirect content the agent reads back via RAG), so an attacker who can influence the prompt can read or destroy all graph data and, when APOC or dbms.security procedures are enabled on the server, achieve OS-command and filesystem access. This is the same defect class and threat model as the SQLChatAgent prompt-to-SQL-to-RCE issue fixed in version 0.63.0 (CVE-2026-25879); that fix did not extend to the neo4j module.

Technical detail

Untrusted-input to sink trace (reviewed on langroid HEAD b9df06f, v0.65.3):

  1. Tool schemas accept raw query text from the LLM. langroid/agent/special/neo4j/tools.py:4-9 (CypherRetrievalTool.cypher_query: str) and :15-21 (CypherCreationTool.cypher_query: str). These tools are enabled unconditionally in neo4j_chat_agent.py:412-419 (enable_message([GraphSchemaTool, CypherRetrievalTool, CypherCreationTool, DoneTool])).

  2. Read path. neo4j_chat_agent.py:300 cypher_retrieval_tool(msg) -> :325 query = msg.cypher_query -> :328 self.read_query(query) -> :223 session.run(query, parameters). The LLM-controlled string is the first positional argument to session.run; parameters is None. No validation occurs between :325 and :223.

  3. Write path. neo4j_chat_agent.py:338 cypher_creation_tool(msg) -> :348 query = msg.cypher_query -> :351 self.write_query(query) -> :276 session.write_transaction(lambda tx: tx.run(query, parameters)). The only inspection of the string (write_query :251-264) is a query.upper() substring test for CREATE/MERGE/CONSTRAINT/INDEX whose sole effect is setting self.config.database_created = True; it blocks nothing. A query such as MATCH (n) DETACH DELETE n (the same statement the built-in remove_database helper runs at :287-293) passes unrestricted.

  4. Guarded-sibling contrast proving the incomplete fix. The SQLChatAgent, patched for the parent CVE, validates every query before execution. langroid/agent/special/sql/sql_chat_agent.py:256 defines allow_dangerous_operations: bool = False (opt-in gate); :618 _validate_query runs (a) a dangerous-pattern regex blocklist (_DANGEROUS_SQL_PATTERNS, :628-641), (b) a sqlglot statement-type allowlist defaulting to SELECT-only (:643-686), and (c) an AST-level dangerous-function blocklist (:687-704). run_query calls rejection = self._validate_query(query) at :721 before executing. The neo4j read_query/write_query paths have no equivalent: a grep for _validate_query/allow_dangerous in neo4j_chat_agent.py returns nothing. The defense exists for SQL and is simply absent for Cypher, which is the definition of an incomplete fix for the same prompt-to-query-language injection class.

Proof of concept (static, no third-party systems, no live Neo4j required)

Step 1 (presence vs absence of the guard, one command):

grep -n "_validate_query\|allow_dangerous" langroid/agent/special/sql/sql_chat_agent.py    # SQL: many hits (gate + validator + call site :721)
grep -n "_validate_query\|allow_dangerous" langroid/agent/special/neo4j/neo4j_chat_agent.py # neo4j: ZERO hits

Step 2 (sink trace is direct, no interposed check):

read_query:  msg.cypher_query (line 325) -> read_query(query) (328) -> session.run(query, parameters) (223)
write_query: msg.cypher_query (348) -> write_query(query) (351) -> tx.run(query, parameters) (276)

The only string inspection (write_query 251-264) is a .upper() substring test that only sets database_created=True and rejects nothing. The asymmetry (validator + opt-out gate enforced on every SQL query at sql_chat_agent.py:721; nothing on either Cypher path) is the deterministic artifact: the same project, for the same injection class, guards one query language and not the other. A dynamic confirmation against an operator-owned disposable Neo4j (create a CSPRNG-marked…

Record
GHSA-2pq5-3q89-j7cc
CVSS 4.0
9.2 CriticalCVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Weakness
CWE-74
Updated
2026-11-02
OSVPYSEC-2026-2576 9.2

Langroid: Neo4jChatAgent executes LLM-generated Cypher without validation (prompt-to-Cypher injection; config-conditional RCE), mirroring the SQLChatAgent bug fixed in CVE-2026-25879

Neo4jChatAgent passes LLM-generated Cypher queries straight to the Neo4j driver with no validation, no statement-type allowlist, and no opt-out gate. The query text is influenceable by prompt injection (direct user input or indirect content the agent reads back via RAG), so an attacker who can influence the prompt can read or destroy all graph data and, when APOC or dbms.security procedures are enabled on the server, achieve OS-command and filesystem access. This is the same defect class and threat model as the SQLChatAgent prompt-to-SQL-to-RCE issue fixed in version 0.63.0 (CVE-2026-25879); that fix did not extend to the neo4j module.

Technical detail

Untrusted-input to sink trace (reviewed on langroid HEAD b9df06f, v0.65.3):

  1. Tool schemas accept raw query text from the LLM. langroid/agent/special/neo4j/tools.py:4-9 (CypherRetrievalTool.cypher_query: str) and :15-21 (CypherCreationTool.cypher_query: str). These tools are enabled unconditionally in neo4j_chat_agent.py:412-419 (enable_message([GraphSchemaTool, CypherRetrievalTool, CypherCreationTool, DoneTool])).

  2. Read path. neo4j_chat_agent.py:300 cypher_retrieval_tool(msg) -> :325 query = msg.cypher_query -> :328 self.read_query(query) -> :223 session.run(query, parameters). The LLM-controlled string is the first positional argument to session.run; parameters is None. No validation occurs between :325 and :223.

  3. Write path. neo4j_chat_agent.py:338 cypher_creation_tool(msg) -> :348 query = msg.cypher_query -> :351 self.write_query(query) -> :276 session.write_transaction(lambda tx: tx.run(query, parameters)). The only inspection of the string (write_query :251-264) is a query.upper() substring test for CREATE/MERGE/CONSTRAINT/INDEX whose sole effect is setting self.config.database_created = True; it blocks nothing. A query such as MATCH (n) DETACH DELETE n (the same statement the built-in remove_database helper runs at :287-293) passes unrestricted.

  4. Guarded-sibling contrast proving the incomplete fix. The SQLChatAgent, patched for the parent CVE, validates every query before execution. langroid/agent/special/sql/sql_chat_agent.py:256 defines allow_dangerous_operations: bool = False (opt-in gate); :618 _validate_query runs (a) a dangerous-pattern regex blocklist (_DANGEROUS_SQL_PATTERNS, :628-641), (b) a sqlglot statement-type allowlist defaulting to SELECT-only (:643-686), and (c) an AST-level dangerous-function blocklist (:687-704). run_query calls rejection = self._validate_query(query) at :721 before executing. The neo4j read_query/write_query paths have no equivalent: a grep for _validate_query/allow_dangerous in neo4j_chat_agent.py returns nothing. The defense exists for SQL and is simply absent for Cypher, which is the definition of an incomplete fix for the same prompt-to-query-language injection class.

Proof of concept (static, no third-party systems, no live Neo4j required)

Step 1 (presence vs absence of the guard, one command):

grep -n "_validate_query\|allow_dangerous" langroid/agent/special/sql/sql_chat_agent.py    # SQL: many hits (gate + validator + call site :721)
grep -n "_validate_query\|allow_dangerous" langroid/agent/special/neo4j/neo4j_chat_agent.py # neo4j: ZERO hits

Step 2 (sink trace is direct, no interposed check):

read_query:  msg.cypher_query (line 325) -> read_query(query) (328) -> session.run(query, parameters) (223)
write_query: msg.cypher_query (348) -> write_query(query) (351) -> tx.run(query, parameters) (276)

The only string inspection (write_query 251-264) is a .upper() substring test that only sets database_created=True and rejects nothing. The asymmetry (validator + opt-out gate enforced on every SQL query at sql_chat_agent.py:721; nothing on either Cypher path) is the deterministic artifact: the same project, for the same injection class, guards one query language and not the other. A dynamic confirmation against an operator-owned disposable Neo4j (create a CSPRNG-marked…

Record
PYSEC-2026-2576
CVSS 4.0
9.2 CriticalCVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
langroid
PyPI
through 0.65.4
0.65.5
langroid
PyPI
before 0.65.5, plus listed versions
0.1.1000.1.1010.1.1020.1.1030.1.104
Show 45 moreShow less
0.1.1050.1.1060.1.1070.1.1080.1.1090.1.110.1.1100.1.1110.1.1120.1.1130.1.1140.1.1170.1.1180.1.1190.1.120.1.1200.1.1210.1.1220.1.1230.1.1240.1.1250.1.1260.1.1270.1.1280.1.1290.1.130.1.1300.1.1310.1.1320.1.1330.1.1340.1.1350.1.1360.1.1370.1.1380.1.1390.1.1400.1.1410.1.1420.1.1430.1.1440.1.1450.1.1470.1.1480.1.149
0.65.5

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-55615 is a critical vulnerability (CVSS 9.2) in Langroid, published July 6, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.46%, the 40th percentile. Fixed in langroid 0.65.5.

References

This page doesn't list everything

Left out here: 487 versions and the rest of 3 source descriptions. The JSON record has them.

MoveEnter Open