
pgAdmin 4의 AI 어시스턴트에서 sqlparse/PostgreSQL 렉서 차이를 통한 CVE-2026-17351 SQL 인젝션 우회를 시연하는 개념 증명(Proof-of-concept)으로, 간접 프롬프트 인젝션 전달을 포함합니다.
CVE-2026-17351에 대한 PoC로, pgAdmin 4의 AI 어시스턴트에서 발생하는 치명적(CVSS 9.0) SQL 인젝션 우회입니다.
pgAdmin 4 버전 9.13~9.16은 Python sqlparse 라이브러리를 사용하여 LLM이 생성한 SQL 쿼리가 단일 읽기 전용 문장인지 검증합니다. PostgreSQL의 standard_conforming_strings = on(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
# 메인 PoC — 렉서 차이 데모
python3 poc.py
# 프롬프트 인젝션 전달 데모
python3 prompt_injection_demo.py
# 사용자 지정 연결 매개변수
python3 poc.py --host 10.0.0.5 --port 5432 --user postgres --password mypw
수정은 psycopg3의 확장 쿼리 프로토콜을 강제하는 방식입니다:
conn.prepare_threshold = 0 설정cursor.execute()에 prepare=True 전달이렇게 하면 PostgreSQL 자체의 Parse 단계가 문장 경계에 대한 권위자가 되어 클라이언트 측 렉서가 어떻게 분류하든 다중 문장 텍스트를 구조적으로 거부합니다.
이 PoC는 교육 및 승인된 테스트 목적으로만 제공됩니다.