CRITICAL🇬🇧 English

CVE-2026-17566

pgAdmin 4: RCE przez command injection w narzędziu Import/Export Data

CVSS 9.4v4.0pub. 2026-07-31upd. 2026-08-05

Podatność w pgAdmin 4 pozwala uwierzytelnionemu użytkownikowi z uprawnieniami do narzędzia Import/Export Data na wykonanie dowolnych poleceń systemowych na serwerze. Wynika z błędnej walidacji zapytania SQL przekazywanego do polecenia psql \copy, co umożliwia wstrzyknięcie klauzuli TO PROGRAM wykonującej kod przez popen().

Pokaż oryginał (EN)

pgAdmin 4's Import/Export Data tool builds a psql \copy (...) command line by interpolating a user-supplied SQL query into a Jinja template and passing the rendered line to psql via --command. To stop an attacker from breaking out of the (...) wrapper, create_import_export_job() (route POST /import_export/job/<sid>, gated only by the ordinary, commonly-granted tools_import_export_data permission) validated the query with a hand-written parenthesis-balance checker, _is_query_parens_balanced(). That checker always treated a backslash before a single quote (\') as escaping the quote, i.e. as if standard_conforming_strings were off. PostgreSQL has defaulted standard_conforming_strings to on since 9.1 (2010), the default on every PostgreSQL version pgAdmin 4 currently supports (13-18); under that default psql's own \copy tokenizer treats \ as an ordinary character, so a single quote immediately after it closes the string literal. A query such as SELECT 'a\') TO PROGRAM 'echo pwned' x' was therefore accepted as "balanced" by pgAdmin's checker (which believed the ) was still inside the string), while psql, run through the actual rendered command line, closes the string at that point and treats the following ) as the end of the wrapping \copy (...) subquery, exposing an attacker-chosen TO PROGRAM '<command>' clause that psql executes via popen() -- independent of a subsequent syntax error later on the same line. This is the same class of bug as CVE-2025-12762/CVE-2025-13780 (RCE via psql meta-command/COPY injection during PLAIN-format dump restore), reached through an independently written defense in a different module (Import/Export Data rather than Restore) that had its own, different logic bug (inverted backslash-escape semantics rather than a BOM-defeated regex anchor). The fix rejects any backslash inside a single-quoted string in the query outright, rather than picking one of the two possible psql interpretations. This is intentionally conservative: because the correct interpretation of \ depends on the target server's standard_conforming_strings setting, which the checker cannot reliably know at validation time, refusing the query is safer than guessing. This issue affects pgAdmin 4: from the introduction of _is_query_parens_balanced() before 9.18.

🤖 Analiza AI
Jak działa

Narzędzie Import/Export Data buduje polecenie psql \copy (...) przez interpolację zapytania SQL dostarczonego przez użytkownika do szablonu Jinja i przekazanie go do psql przez --command. Aby zapobiec ucieczce z wrappera (...), funkcja _is_query_parens_balanced() walidowała zapytanie ręcznie napisanym sprawdzaniem balansu nawiasów, który traktował sekwencję \' jako escape'owanie cudzysłowu — zgodnie z zachowaniem przy wyłączonym standard_conforming_strings. PostgreSQL domyślnie włącza standard_conforming_strings od wersji 9.1 (2010), co oznacza, że psql traktuje backslash jako zwykły znak, a apostrof po nim zamyka literał stringowy. Zapytanie takie jak SELECT 'a\') TO PROGRAM 'echo pwned' x' było przez pgAdmin uznawane za poprawnie zbilansowane (checker uważał, że nawias jest nadal wewnątrz stringa), podczas gdy psql zamykał string i interpretował ) jako koniec subzapytania \copy, odsłaniając atakującemu kontrolowaną klauzulę TO PROGRAM wykonywaną przez popen().

Skutki

Uwierzytelniony atakujący posiadający typowo nadawane uprawnienie tools_import_export_data może wykonać dowolne polecenia systemowe na serwerze z uprawnieniami procesu pgAdmin/psql, uzyskując pełną kontrolę nad systemem i potencjalnie nad powiązaną infrastrukturą.

Mitygacja

Należy zaktualizować pgAdmin 4 do wersji 9.18 lub nowszej, w której zastosowano poprawkę odrzucającą każdy backslash wewnątrz apostrofowanego stringa w zapytaniu. Poprawka dostępna jest w commicie 1496fabe28c9f825f6bac0f0d000d9d3276322c3 w repozytorium pgadmin-org/pgadmin4. Do czasu aktualizacji należy ograniczyć nadawanie uprawnienia tools_import_export_data wyłącznie do zaufanych użytkowników.

Kogo dotyczy

pgAdmin 4 we wszystkich wersjach od momentu wprowadzenia funkcji _is_query_parens_balanced() do wersji 9.18 (wersje starsze niż 9.18)

Uwagi

Podatność należy do tej samej klasy błędów co CVE-2025-12762 i CVE-2025-13780 (RCE przez wstrzyknięcie meta-komend psql podczas przywracania dumpów w formacie PLAIN), jednak dotyczy niezależnie napisanej obrony w innym module (Import/Export Data zamiast Restore) z odmiennym błędem logicznym — odwróconą semantyką escape'owania backslashem.

CVSS Vector
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
  • Pgadmin 4

    APP
    Pgadmin
    < 9.18
🔵
ZWERYFIKUJ U PRODUCENTA
Brak jednoznacznych danych o patchu. Sprawdź referencje od producenta.
Tagi
SQLiCommand Injection
CWE
Referencje

Powiązane podatności

CVE-2026-17351CRITICAL9.4PL ✓ten sam produkt

SQL injection bypass w pgAdmin 4 AI Assistant via sqlparse — obejście transakcji READ ONLY

CVE-2026-17349CRITICAL9.3PL ✓ten sam produkt

pgAdmin 4: kradzież poświadczeń przez nieuprawniony klon serwera (adhoc connect)

CVE-2026-12045CRITICAL9.4PL ✓ten sam produkt

pgAdmin 4 AI Assistant: ominięcie transakcji read-only i RCE via prompt injection

CVE-2026-12046CRITICAL9.5PL ✓ten sam produkt

pgAdmin 4: brak uwierzytelnienia na endpointach SQL Editor z deserialization RCE

CVE-2026-12048CRITICAL9.3PL ✓ten sam produkt

Stored XSS w pgAdmin 4 — wstrzyknięcie HTML przez komunikaty PostgreSQL