The pgAdmin Development Team is pleased to announce the release of pgAdmin 4 version 9.18. This release of pgAdmin 4 includes 29 bug fixes and new features, including fixes for four security vulnerabilities (CVE-2026-86861 through CVE-2026-86864). For more details, please see the release notes.
pgAdmin is the leading open-source graphical management tool for PostgreSQL. For more information, please see the website.
Notable changes in this release include:
Ctrl+Alt+B
by default, does the same thing and can be changed through the new toggle_object_explorer
preference.'unsafe-inline'
, and drop 'unsafe-eval'
. style-src
keeps 'unsafe-inline'
, because MUI and React inject runtime styles and inline style
attributes that cannot carry a nonce, and development bundles have 'unsafe-eval'
re-added automatically when DEBUG
is set.get_user()
fell back to reading the configured WEBSERVER_REMOTE_USER
name from the inbound request headers when it was absent from the WSGI environment. Because a header is written by whoever sends the request, any client that could reach pgAdmin could assert any identity, including an administrator's, without presenting a credential. A header-asserted identity is now opt-in, restricted to a configured list of trusted proxies with an optional shared secret, and refused for accounts whose authentication source is not webserver
(CVE-2026-86863).pg_dump
argument vector as a bare positional value. Because getopt_long
permutes arguments, a value beginning with a dash supplied further options such as --file
, overriding the storage-confined output path; and because libpq expands a database name containing an equals sign into a full connection string, the same field could redirect the connection, and the password exported in PGPASSWORD
, to a host of the caller's choosing. The database name is now passed through the PGDATABASE
environment variable, which libpq never expands (CVE-2026-86864).--dbname
and could likewise redirect the connection, and the exported password, to a server of the caller's choosing (CVE-2026-86862).save_file
endpoint, which backs saving from the Query Tool and ERD: the requested path was validated with check_access_permission()
and then opened with a plain open()
, so a symbolic link planted in between was followed, writing outside the user's storage directory. This is the write sink that CVE-2026-7819's hardening of the separate upload path did not cover (CVE-2026-86861).Location
header on to a destination the ALLOWED_LLM_API_URLS
check was never applied to. This is hardening rather than a fix for an exploitable flaw, since returning the redirect at all requires control of a host already on the allowlist.Username
when importing a non-shared server, which previously imported cleanly and left a server that libpq would silently authenticate as the OS account running pgAdmin rather than reject outright.UserMixin.is_locked()
that pgAdmin's own is_locked()
had been written against.dependLevel
unset.getNodeAjaxOptions()
so a wide table's Columns tab no longer fires one duplicate get_types
request per column row.TABLESPACE pg_default
clause from generated index SQL, which was invalid on a partitioned table.pg_service.conf
) connection, which leaves host, port and username unset.SharedUsername
when importing a shared server from a servers.json
definition, instead of insisting on Username
for every server.ProductVersion
, and fix the existingSecret
path in the Helm deployment template.SERVER_MODE
is set, leaving desktop mode with internal authentication alone.Builds for Windows and macOS are available now, along with a Python Wheel, Docker Container, RPM, DEB Package, and source code tarball from the download area.
