
Prova de conceito de exploit para CVE-2025-67644, uma vulnerabilidade de injeção SQL no LangGraph SQLite Checkpoint. Demonstra injeção SQL arbitrária por meio de chaves de filtro de metadados não sanitizadas, possibilitando exfiltração de dados e bypass de filtro.
CVE-2025-67644 é uma vulnerabilidade de Injeção SQL (CWE-89) no pacote langgraph-checkpoint-sqlite (parte do ecossistema LangGraph / LangChain).
Permite que um atacante injete SQL arbitrário através de chaves de filtro de metadados não sanitizadas, passadas para os métodos list() / de .
alist()SqliteSaverImpacto: Bypass completo de filtros, vazamento de todos os registros de checkpoint (incluindo estado potencialmente sensível de conversas, IDs de thread, metadados) e, em alguns cenários de implantação — acesso mais amplo ao banco de dados.
Versões afetadas: < 3.0.1
Corrigido em: ≥ 3.0.1
Pontuação CVSS: 7.3 (Alta) — AV:L / AC:L / PR:L / UI:N / S:C / C:H / I:L / A:N
A lógica interna _metadata_predicate() usava interpolação insegura de f-string em chaves de dicionário controladas pelo usuário dentro de uma expressão de extração JSON:
f"json_extract(CAST(metadata AS TEXT), '$.{query_key}')"
Um atacante que pode fornecer chaves arbitrárias (por exemplo, via entrada de API) pode fechar o caminho JSON precocemente e injetar fragmentos SQL, como:
{"env') OR '1'='1": "anything"}
→ resultando em uma cláusula WHERE que sempre é avaliada como verdadeira → retorna todos os registros.
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"](Esta versão evita parênteses no texto dos nós quando possível e usa aspas ao redor de rótulos com caracteres especiais/pontos para prevenir erros de análise.)
--dump-all (mostrar registros completos), --threads-only (extrair apenas thread_ids)pip install langgraph-checkpoint-sqlite"<3.0.1" # ex.: ==2.0.0
# Verificação básica (apenas contagem)
python3 exploit.py checkpoints.db
# Despejar detalhes completos do checkpoint
python3 exploit.py checkpoints.db --dump-all
# Extrair apenas thread_ids (útil para enumeração)
python3 exploit.py checkpoints.db --threads-only --dump-all
# Testar com banco em memória (rápido e volátil)
python3 exploit.py ":memory:" --dump-all
Instale a versão vulnerável:
pip install langgraph-checkpoint-sqlite==2.0.0
Salve o código do exploit como exploit.py
Execute contra um banco de dados de checkpoint existente ou novo:
python3 exploit.py checkpoints.db --dump-all
Atualize imediatamente:
pip install --upgrade langgraph-checkpoint-sqlite
(versão ≥ 3.0.1)
Não aceite chaves de filtro de metadados arbitrárias de fontes não confiáveis (usuários, APIs, payloads JSON, etc.)
Na versão ≥ 3.0.1 a biblioteca impõe uma regex rigorosa nas chaves: ^[a-zA-Z0-9_.-]+$
Esta é uma prova de conceito divulgada apenas para fins educacionais e de pesquisa em segurança.
Não utilize este código contra sistemas de produção ou qualquer alvo sem permissão explícita por escrito.
O autor não é responsável pelo mau uso ou danos causados por este código.
Divulgação responsável e pesquisa apenas.
Mohammed Idrees Banyamer
@banyamer_security