{"id":"CVE-2026-116249","state":"PUBLISHED","title":"pgAdmin 4: Connection file paths and parameter keys escape the user's storage directory","description":"In server mode pgAdmin 4 resolves a server's password file, SSL certificate, key, CRL and SSH tunnel identity file relative to the user's storage directory, but get_complete_file_path() only stripped leading slashes before joining the two. A path such as \"../<another user>/.pgpass\", set through the server dialog, the REST API or a servers.json import, therefore named another user's file, and connecting used that user's saved passwords, client certificate or SSH key. The sslkeylogfile connection parameter was passed to libpq unchanged, so a path outside storage let libpq create or append a file as the account running pgAdmin.\n\nmake_conninfo() also quoted connection parameter values but not their names, so a crafted parameter name could smuggle additional keyword=value pairs past these checks.\n\nThe fix requires the resolved path, with symbolic links followed, to stay inside the user's storage directory or the named shared storage directory, confines sslkeylogfile the same way, and accepts only exact libpq keywords as connection parameter names. A refused path or keyword is reported instead of letting libpq fall back to a default.\n\nThis issue affects pgAdmin 4: before 9.19.","publishedAt":"2026-10-30T19:55:18.121Z","updatedAt":"2026-10-30T19:55:18.121Z","severity":{"score":7.2,"label":"High","version":"4.0","vector":"CVSS:4.0/AV:N/AC:H/AT:P/PR:L/UI:N/VC:H/VI:L/VA:L/SC:H/SI:H/SA:N","source":"PostgreSQL"},"assigner":"PostgreSQL","products":["pgadmin.org pgAdmin 4"],"affected":[{"vendor":"pgadmin.org","product":"pgAdmin 4","defaultStatus":"unaffected","versions":[{"version":"0","status":"affected","lessThan":"9.19","versionType":"custom"}],"repo":"https://github.com/pgadmin-org/pgadmin4","modules":["Servers","Import/Export Servers"],"programFiles":["https://github.com/pgadmin-org/pgadmin4/blob/master/web/pgadmin/utils/__init__.py","https://github.com/pgadmin-org/pgadmin4/blob/master/web/pgadmin/utils/driver/psycopg3/server_manager.py"]}],"references":["https://github.com/pgadmin-org/pgadmin4/issues/10650","https://github.com/pgadmin-org/pgadmin4/commit/2afe505ef4a31591796449d54ab1604355ff06c2"],"weaknesses":["CWE-22","CWE-73"],"ingestedAt":"2026-10-30T20:04:06.178Z","source":{"repository":"CVEProject/cvelistV5","path":"cves/2026/116xxx/CVE-2026-116249.json","commit":"7684a5927aa3dceabed8dec00447545f1b10f31f","baselineCommit":"556c9d3a8cd17e218bb8e452ba7cd619a384ff47"},"raw":{"dataType":"CVE_RECORD","dataVersion":"5.2","cveMetadata":{"cveId":"CVE-2026-116249","state":"PUBLISHED","datePublished":"2026-10-30T19:55:18.121Z","dateUpdated":"2026-10-30T19:55:18.121Z","assignerShortName":"PostgreSQL","assignerOrgId":"f86ef6dc-4d3a-42ad-8f28-e6d5547a5007","dateReserved":"2026-10-25T16:26:16.420Z"},"containers":{"cna":{"title":"pgAdmin 4: Connection file paths and parameter keys escape the user's storage directory","descriptions":[{"lang":"en","value":"In server mode pgAdmin 4 resolves a server's password file, SSL certificate, key, CRL and SSH tunnel identity file relative to the user's storage directory, but get_complete_file_path() only stripped leading slashes before joining the two. A path such as \"../<another user>/.pgpass\", set through the server dialog, the REST API or a servers.json import, therefore named another user's file, and connecting used that user's saved passwords, client certificate or SSH key. The sslkeylogfile connection parameter was passed to libpq unchanged, so a path outside storage let libpq create or append a file as the account running pgAdmin.\n\nmake_conninfo() also quoted connection parameter values but not their names, so a crafted parameter name could smuggle additional keyword=value pairs past these checks.\n\nThe fix requires the resolved path, with symbolic links followed, to stay inside the user's storage directory or the named shared storage directory, confines sslkeylogfile the same way, and accepts only exact libpq keywords as connection parameter names. A refused path or keyword is reported instead of letting libpq fall back to a default.\n\nThis issue affects pgAdmin 4: before 9.19."}],"affected":[{"vendor":"pgadmin.org","product":"pgAdmin 4","defaultStatus":"unaffected","versions":[{"version":"0","status":"affected","lessThan":"9.19","versionType":"custom"}],"repo":"https://github.com/pgadmin-org/pgadmin4","modules":["Servers","Import/Export Servers"],"programFiles":["https://github.com/pgadmin-org/pgadmin4/blob/master/web/pgadmin/utils/__init__.py","https://github.com/pgadmin-org/pgadmin4/blob/master/web/pgadmin/utils/driver/psycopg3/server_manager.py"]}],"references":[{"url":"https://github.com/pgadmin-org/pgadmin4/issues/10650","tags":["issue-tracking"]},{"url":"https://github.com/pgadmin-org/pgadmin4/commit/2afe505ef4a31591796449d54ab1604355ff06c2","tags":["patch"]}],"metrics":[{"format":"CVSS","scenarios":[{"lang":"en","value":"Any authenticated user who can register a server. Attack Complexity is High: the victim must keep such a file in their storage directory, and the attacker must know its name and a host and role it is accepted for. Scope is Changed because the connection is made to a database server with another user's credentials, an authority the attacker was never given; Confidentiality and Integrity are High for that access. Availability is Low for the file sslkeylogfile can create or append to outside storage."}],"cvssV3_1":{"version":"3.1","attackVector":"NETWORK","attackComplexity":"HIGH","privilegesRequired":"LOW","userInteraction":"NONE","scope":"CHANGED","confidentialityImpact":"HIGH","integrityImpact":"HIGH","availabilityImpact":"LOW","baseSeverity":"HIGH","baseScore":8.4,"vectorString":"CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:L"}},{"format":"CVSS","scenarios":[{"lang":"en","value":"Same reasoning as the CVSS 3.1 entry. AT:P for the victim's file and its name, which the attacker does not control. VC:H for the credential read through pgAdmin, VI:L/VA:L for the sslkeylogfile write; SC:H/SI:H for the database server reached with the other user's identity."}],"cvssV4_0":{"version":"4.0","vectorString":"CVSS:4.0/AV:N/AC:H/AT:P/PR:L/UI:N/VC:H/VI:L/VA:L/SC:H/SI:H/SA:N","baseScore":7.2,"baseSeverity":"HIGH"}}],"problemTypes":[{"descriptions":[{"cweId":"CWE-22","lang":"en","description":"CWE-22 Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')","type":"CWE"},{"cweId":"CWE-73","lang":"en","description":"CWE-73 External Control of File Name or Path","type":"CWE"}]}],"providerMetadata":{"shortName":"PostgreSQL","orgId":"f86ef6dc-4d3a-42ad-8f28-e6d5547a5007","dateUpdated":"2026-10-30T19:55:18.121Z"},"datePublic":"2026-10-29T00:00:00.000Z","credits":[{"lang":"en","value":"Dave Page <dpage@pgadmin.org>","type":"remediation developer"},{"lang":"en","value":"Kundan Sable <kundan.sable@enterprisedb.com>","type":"remediation reviewer"},{"lang":"en","value":"Hitesh Jambhale <hitesh.jambhale@enterprisedb.com>","type":"remediation reviewer"},{"lang":"en","value":"Ashesh Vashi <ashesh.vashi@enterprisedb.com>","type":"remediation reviewer"}],"source":{"discovery":"INTERNAL"}}}}}