
Доказательство концепции, демонстрирующее обход SQL-инъекции CVE-2026-17351 в ИИ-ассистенте pgAdmin 4 через расхождение лексеров sqlparse/PostgreSQL, включая доставку непрямой промпт-инъекции.
PoC для CVE-2026-17351 — критический (CVSS 9.0) обход SQL-инъекции в AI-ассистенте pgAdmin 4.
Версии pgAdmin 4 с 9.13 по 9.16 используют библиотеку Python sqlparse для проверки того, что SQL-запросы, сгенерированные LLM, являются одиночными операторами «только чтение». При standard_conforming_strings = on в PostgreSQL (значение по умолчанию с PostgreSQL 9.1) sqlparse и PostgreSQL расходятся во мнениях о том, как обрабатываются обратные слэши внутри строковых литералов. Это позволяет атакующему создать полезную нагрузку, которая проходит проверку sqlparse как одиночный SELECT, но выполняется в PostgreSQL как четыре оператора — включая COMMIT, завершающий транзакцию «только чтение», и последующие операторы записи.
SELECT '\';COMMIT;CREATE TABLE pwn(x int);SELECT 1 --'
SELECT с большим строковым литералом → проверка проходитSELECT '\' + COMMIT + CREATE TABLE pwn(x int) + SELECT 1 --'Полезная нагрузка доставляется через непрямую инъекцию в промпт: атакующий внедряет её в объект базы данных (комментарий к столбцу, значение строки, определение представления), который читает AI-ассистент. Когда легитимный пользователь задаёт вопрос, LLM читает отравленные данные и передаёт их как вызов инструмента execute_sql_query.
| Файл | Описание |
|---|---|
poc.py | Демонстрирует расхождение лексеров: проверка sqlparse проходит, простой протокол запросов выполняет несколько операторов, расширенный протокол запросов блокирует их |
prompt_injection_demo.py | Имитирует полную цепочку атаки: полезная нагрузка внедрена как комментарий к столбцу → имитированный LLM читает её → проверка проходит → выполнение |
pip install psycopg[binary] sqlparse
Также вам понадобится запущенный экземпляр PostgreSQL (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
Исправление принудительно включает расширенный протокол запросов psycopg3:
conn.prepare_threshold = 0 на выделенном соединении LLMprepare=True в cursor.execute()Благодаря этому собственный шаг Parse PostgreSQL становится источником истины для границ операторов — он структурно отклоняет многооператорный текст независимо от того, как любой клиентский лексер его классифицирует.
Этот PoC предназначен только для образовательных целей и авторизованного тестирования.