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

GHSA-9rwj-6rc7-p77c HIGH
Published December 10, 2025
CISO Take

If you run LangGraph with SqliteSaver and expose state history endpoints that accept user-controlled filter field names, patch to langgraph-checkpoint-sqlite 3.0.1 immediately. LangSmith-hosted deployments are unaffected — the risk is limited to custom server deployments where untrusted input reaches checkpoint filter keys. Audit any API endpoint that forwards user-supplied field names to get_state_history() or saver.list() before patching is complete.

Risk Assessment

Effective risk is moderate-to-high for specific deployment patterns despite CVSS 7.3. EPSS of 0.00023 indicates no observed exploitation in the wild. The vulnerability requires a precise architectural condition: an exposed endpoint that passes untrusted filter key names directly to SQLite checkpoint queries. In multi-tenant agent deployments, this breaks data isolation between users or sessions. The vast majority of LangGraph deployments (particularly LangSmith-hosted) are unaffected, which substantially limits the attack surface.

Affected Systems

Package Ecosystem Vulnerable Range Patched
langgraph-checkpoint-sqlite pip < 3.0.1 3.0.1
31.1K 3.1K dependents Pushed 6d ago 100% patched ~3d to patch Full package profile →

Do you use langgraph-checkpoint-sqlite? You're affected.

Severity & Risk

CVSS 3.1
7.3 / 10
EPSS
0.0%
chance of exploitation in 30 days
Higher than 5% of all CVEs
Exploitation Status
No known exploitation
Sophistication
Trivial

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

Recommended Action

5 steps
  1. Patch: Update langgraph-checkpoint-sqlite to >=3.0.1 immediately.

  2. Audit: Search codebase for calls to saver.list() or get_state_history() where filter key names (not just values) are derived from user input.

  3. Workaround: Until patched, implement an allowlist of valid metadata key names before passing to checkpoint operations — reject any key containing non-alphanumeric or special characters.

  4. Architecture: If filter keys must come from external sources, add a strict validation layer at the API boundary.

  5. Detection: Review application logs for anomalous state history responses returning unexpectedly large result sets, which may indicate bypass exploitation.

CISA SSVC Assessment

Decision Track
Exploitation none
Automatable No
Technical Impact partial

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

Classification

Compliance Impact

This CVE is relevant to:

EU AI Act
Article 15 - Accuracy, robustness and cybersecurity
ISO 42001
A.6.2 - AI system security and data protection A.9.4 - Information security in AI system development
NIST AI RMF
MANAGE-2.2 - Mechanisms to achieve treatment of identified and prioritized AI risks
OWASP LLM Top 10
LLM05 - Supply Chain Vulnerabilities LLM06 - Sensitive Information Disclosure LLM07 - Insecure Plugin Design

Frequently Asked Questions

What is CVE-2025-67644?

If you run LangGraph with SqliteSaver and expose state history endpoints that accept user-controlled filter field names, patch to langgraph-checkpoint-sqlite 3.0.1 immediately. LangSmith-hosted deployments are unaffected — the risk is limited to custom server deployments where untrusted input reaches checkpoint filter keys. Audit any API endpoint that forwards user-supplied field names to get_state_history() or saver.list() before patching is complete.

Is CVE-2025-67644 actively exploited?

No confirmed active exploitation of CVE-2025-67644 has been reported, but organizations should still patch proactively.

How to fix CVE-2025-67644?

1. Patch: Update langgraph-checkpoint-sqlite to >=3.0.1 immediately. 2. Audit: Search codebase for calls to saver.list() or get_state_history() where filter key names (not just values) are derived from user input. 3. Workaround: Until patched, implement an allowlist of valid metadata key names before passing to checkpoint operations — reject any key containing non-alphanumeric or special characters. 4. Architecture: If filter keys must come from external sources, add a strict validation layer at the API boundary. 5. Detection: Review application logs for anomalous state history responses returning unexpectedly large result sets, which may indicate bypass exploitation.

What systems are affected by CVE-2025-67644?

This vulnerability affects the following AI/ML architecture patterns: agent frameworks, stateful AI agents, multi-tenant agent deployments, LangGraph checkpoint-backed applications.

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

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

Technical Details

NVD Description

# Context A SQL injection vulnerability exists in LangGraph's SQLite checkpoint implementation that allows attackers to manipulate SQL queries through metadata filter keys. This affects applications that accept **untrusted metadata filter keys** (not just filter values) in checkpoint search operations. # Impact Attackers who control metadata filter keys can execute arbitrary sql queries against the database. # Root Cause The `_metadata_predicate()` function constructs SQL queries by interpolating filter keys directly into f-strings without validation: ```python # VULNERABLE CODE (before fix) for query_key, query_value in metadata_filter.items(): operator, param_value = _where_value(query_value) predicates.append( f"json_extract(CAST(metadata AS TEXT), '$.{query_key}') {operator}" ) param_values.append(param_value) ``` While filter **values** are parameterized, filter **keys** are not validated, allowing SQL injection. # Attack Example **Before Fix:** ```python from langgraph.checkpoint.sqlite import SqliteSaver saver = SqliteSaver.from_conn_string("checkpoints.db") # Attacker controls the filter keys malicious_filter = {"x') OR '1'='1": "dummy"} # Returns ALL checkpoints, bypassing filtering results = list(saver.list(None, filter=malicious_filter)) ``` **Resulting SQL:** ```sql WHERE json_extract(CAST(metadata AS TEXT), '$.x') OR '1'='1') = ? -- Injected condition makes WHERE clause always true ``` ## Who Is Affected? ### LangSmith Deployment Customers: NOT Impacted **LangSmith deployment customers are NOT affected by this vulnerability.** LangSmith deployments do not allow configuring custom checkpointers, so the vulnerable code path cannot be reached. ### High Risk: Custom Server Deployments You are affected if your application: - Runs a custom server with SqliteSaver checkpointer - Exposes an endpoint for fetching checkpoint history (e.g., via `get_state_history()`) - Accepts metadata filter keys from untrusted sources **Example vulnerable code:** ```python # Custom server endpoint - User controls filter key names - DANGEROUS @app.post("/api/history") def get_history(request): filter_field = request.json.get("filter_field") # Untrusted input filter_value = request.json.get("filter_value") # VULNERABLE: Attacker can bypass access controls history = list(graph.get_state_history( config, filter={filter_field: filter_value} )) return history ``` **Note on privilege escalation:** If an endpoint allows end users to specify arbitrary filter keys, those users likely already have legitimate access to query the checkpoint database. In such cases, this vulnerability may not constitute a privilege escalation, as users who can control filter keys would typically already be expected to have database access. However, the SQL injection still allows bypassing intended filtering logic and metadata-based access controls that the application may rely on for data isolation. ### Additional Security Hardening (Defense in Depth) This release also includes hardening improvements: **1. Checkpoint Limit Parameter**: used f-string interpolation into parameterized query. Not considered a vulnerability as it requires users to accept untrusted input and not validate it against the actual API signature. **2. Store Filter Value Parameterization**: Refactored all filter value handling from manual quote escaping to parameterized queries ## Remediation ### Immediate Actions 1. **Update to the patched version** of `langgraph-checkpoint-sqlite` 2. **Audit your code** for locations where filter keys come from untrusted sources

Exploitation Scenario

An adversary targeting a multi-tenant LangGraph application discovers that the /api/history endpoint accepts a JSON body with filter_field and filter_value parameters that are forwarded directly to the checkpoint query. By submitting filter_field as "x') OR '1'='1" with any dummy value, the attacker causes the SQL WHERE clause to evaluate as always-true, returning ALL stored agent checkpoints across all users. This bypasses tenant isolation and exposes conversation history, tool call outputs, and intermediate reasoning steps from other users' sessions — potentially including credentials passed through agent workflows or sensitive business context stored in agent memory.

CVSS Vector

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

Timeline

Published
December 10, 2025
Last Modified
December 24, 2025
First Seen
March 24, 2026

Related Vulnerabilities