CVE-2026-86863

Source
https://cve.org/CVERecord?id=CVE-2026-86863
Import Source
https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-86863.json
JSON Data
https://api.osv.dev/v1/vulns/CVE-2026-86863
Downstream
CGA (2)
Published
2026-09-17T15:30:58Z
Modified
2026-09-25T03:48:39Z
Severity
  • 9.3 (Critical) CVSS_V4 - CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N CVSS Calculator
Summary
pgAdmin 4: Authentication bypass via a client-controlled identity header in Webserver authentication mode
Details

pgAdmin 4's Webserver authentication source is intended to accept an identity asserted by the web server or reverse proxy in front of pgAdmin, delivered through the WSGI/CGI environment. WebserverAuthentication.get_user() read config.WEBSERVER_REMOTE_USER from request.environ and, when that returned nothing, fell back to reading the same name directly from the inbound HTTP request headers via request.headers.get(). An inbound HTTP header is written by whoever sends the request, so any client able to reach pgAdmin could supply that header itself and be authenticated as any username it named, including an existing Administrator, without presenting a password or any other credential. The environment lookup could also be satisfied by a client-supplied header whenever WEBSERVER_REMOTE_USER was configured to an HTTP_-prefixed or hyphenated name such as HTTP_X_FORWARDED_USER or X-Forwarded-User, since WSGI servers place inbound headers into the environment under exactly those names. Deployments are affected only when 'webserver' is enabled in AUTHENTICATION_SOURCES.

The fix distinguishes a genuine CGI/WSGI variable from a header-derived one and implicitly trusts only the former. A header-asserted identity is now accepted only when the operator explicitly opts in via WEBSERVER_REMOTE_USER_FROM_HEADER, the request arrives from a peer listed in WEBSERVER_TRUSTED_PROXIES, and, when configured, a shared secret supplied in WEBSERVER_SHARED_SECRET_HEADER matches WEBSERVER_SHARED_SECRET under a constant-time comparison. The trusted-peer check deliberately reads the real socket peer address rather than request.remote_addr, because ProxyFix rewrites the latter from the client-controlled X-Forwarded-For header and would otherwise allow an attacker to claim to be the trusted proxy. As defence in depth, login() now refuses any account whose auth_source is not 'webserver', so a misconfigured trust gate cannot be used to assume an internal or LDAP account.

This issue affects pgAdmin 4: from 6.2 before 9.18.

Database specific
{
    "cna_assigner":  "PostgreSQL",
    "cwe_ids":  [
        "CWE-290",
        "CWE-807"
    ],
    "osv_generated_from":  "https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/86xxx/CVE-2026-86863.json"
}
References

Affected packages

Git / github.com/pgadmin-org/pgadmin4

Affected ranges

Type
GIT
Repo
https://github.com/pgadmin-org/pgadmin4
Events
Database specific
Show details
{
    "cpe":  "cpe:2.3:a:pgadmin:pgadmin_4:*:*:*:*:*:postgresql:*:*",
    "extracted_events":  [
        {
            "introduced":  "6.2"
        },
        {
            "fixed":  "9.18"
        }
    ],
    "source":  [
        "AFFECTED_FIELD",
        "CPE_RANGE"
    ]
}

Affected versions

Other
REL-6_10
REL-6_11
REL-6_12
REL-6_13
REL-6_14
REL-6_15
REL-6_16
REL-6_17
REL-6_18
REL-6_19
REL-6_2
REL-6_20
REL-6_21
REL-6_3
REL-6_4
REL-6_5
REL-6_6
REL-6_7
REL-6_8
REL-6_9
REL-7_0
REL-7_1
REL-7_2
REL-7_3
REL-7_4
REL-7_5
REL-7_6
REL-7_7
REL-7_8
REL-8_0
REL-8_1
REL-8_10
REL-8_11
REL-8_12
REL-8_13
REL-8_14
REL-8_2
REL-8_3
REL-8_4
REL-8_5
REL-8_6
REL-8_7
REL-8_8
REL-8_9
REL-9_0
REL-9_1
REL-9_10
REL-9_11
REL-9_12
REL-9_13
REL-9_14
REL-9_15
REL-9_16
REL-9_17
REL-9_2
REL-9_3
REL-9_4
REL-9_5
REL-9_6
REL-9_7
REL-9_8
REL-9_9

Database specific

source
"https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-86863.json"