CVE-2026-17350

Source
https://cve.org/CVERecord?id=CVE-2026-17350
Import Source
https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-17350.json
JSON Data
https://api.osv.dev/v1/vulns/CVE-2026-17350
Published
2026-07-31T16:00:03.744Z
Modified
2026-08-02T03:45:59.560056189Z
Severity
  • 5.3 (Medium) CVSS_V4 - CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N CVSS Calculator
Summary
pgAdmin 4: Tool permission bypass via backend routes and Socket.IO handlers
Details

The per-tool permission system (custom roles / role-based tool permissions, introduced in pgAdmin 4 9.3) did not enforce its permission check consistently. In SERVER mode, pgAdmin 4 gates each tool behind a per-tool Flask-Security permission, but the permission decorator (permissionsrequired) was applied only to a single "front door" route per tool. Every other backend route and Socket.IO handler in that tool's workflow relied solely on pgaloginrequired/socketlogin_required, which check authentication but not the tool permission.

The reporter verified three cases against a test build: (1) a user without toolsquerytool permission received 403 on the protected sqleditor initialization route, but the same session went on to connect the server, initialize the viewdata backend chain, and retrieve real table row content; (2) a user without toolsgrantwizard received 403 on the protected acl route, but the same session still enumerated grantable objects, generated GRANT SQL, and successfully applied it -- confirmed database-side via hastableprivilege(); (3) a user without toolsschemadiff received 403 on the protected panel route, but the same session initialized schema diff, enumerated and connected databases, and obtained real DDL differences via the comparedatabase Socket.IO handler. The reporter also confirmed a related but distinct issue: a non-owner triggering /misc/workspace/adhocconnectserver against an administrator-owned shared server caused pgAdmin to persist a new server row still owned by the administrator (userid/shared unchanged from the source), even though the connection attempt itself reported failure.

During remediation, the same front-door-only permission gap was found to also affect the ERD, PSQL, and Debugger tools, and the Backup, Restore, Maintenance, and Import/Export blueprints, none of which were part of the original report; these were fixed using the same pattern as an extension of the reported defect class.

An authenticated user who had valid pgAdmin login and a stored, working database connection, but had been explicitly denied a specific tool's permission by an administrator, could therefore still drive that tool end-to-end through its other routes and sockets, including obtaining an interactive psql session over the /pty Socket.IO namespace and invoking backup/restore/maintenance/import-export jobs.

Because the bypass only restores access to tools operating over the user's own already-authenticated database connection, it does not grant the user any database privilege they did not already hold; it circumvents pgAdmin's own tool-level access-control policy (an organisational segregation-of-duties control, separate from database-level authorization), letting a user reach a pgAdmin feature an administrator intended to withhold from them, using capabilities their existing database role already permits through other means.

Socket.IO event handlers had no permission-aware equivalent of permissionsrequired; only socketlogin_required existed, checking authentication but not the tool permission.

Fix adds a socketpermissionsrequired decorator (mirroring permissionsrequired, honouring the Administrator bypass, reading permissions via haspermission()) and applies it, alongside permissions_required, as the outermost decorator on every backend route and Socket.IO handler for the affected tools. Regression tests assert 403 on every gated route and socket handler for a permission-less user.

This issue affects pgAdmin 4 in SERVER mode: from 9.3 before 9.17.

Database specific
{
    "cna_assigner": "PostgreSQL",
    "osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/17xxx/CVE-2026-17350.json",
    "unresolved_ranges": [
        {
            "extracted_events": [
                {
                    "introduced": "9.3"
                },
                {
                    "fixed": "9.17"
                }
            ],
            "source": "AFFECTED_FIELD"
        },
        {
            "extracted_events": [
                {
                    "introduced": "9.3"
                },
                {
                    "fixed": "9.17"
                }
            ],
            "source": "DESCRIPTION"
        }
    ],
    "cwe_ids": [
        "CWE-862"
    ]
}
References

Affected packages

Git / github.com/pgadmin-org/pgadmin4

Affected ranges

Type
GIT
Repo
https://github.com/pgadmin-org/pgadmin4
Events
Database specific
{
    "source": "REFERENCES"
}

Affected versions

Other
REL-1_0
REL-1_0-BETA1
REL-1_0-BETA2
REL-1_0-BETA3
REL-1_0-BETA4
REL-1_0-RC1
REL-1_1
REL-1_2
REL-1_3
REL-1_4
REL-1_5
REL-1_6
REL-2_0
REL-2_0-RC1
REL-2_0-RC2
REL-2_1
REL-3_0
REL-3_1
REL-3_2
REL-3_3
REL-3_4
REL-3_5
REL-3_6
REL-4_0
REL-4_1
REL-4_10
REL-4_11
REL-4_12
REL-4_13
REL-4_14
REL-4_15
REL-4_16
REL-4_17
REL-4_18
REL-4_19
REL-4_2
REL-4_20
REL-4_21
REL-4_22
REL-4_23
REL-4_24
REL-4_25
REL-4_26
REL-4_27
REL-4_28
REL-4_29
REL-4_3
REL-4_30
REL-4_4
REL-4_5
REL-4_6
REL-4_7
REL-4_8
REL-4_9
REL-5_0
REL-5_1
REL-5_2
REL-5_3
REL-5_4
REL-5_5
REL-5_6
REL-5_7
REL-6_0
REL-6_1
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_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-17350.json"