CVE-2026-17350: pgAdmin: broken access control bypasses tool permissions

MEDIUM
Published July 31, 2026
CISO Take

pgAdmin 4's per-tool permission system, introduced in 9.3 to let administrators withhold specific features (query tool, grant wizard, schema diff, PSQL, backup/restore) from individual users, only enforced that check on each tool's single "front door" route; every other backend route and Socket.IO handler behind it checked authentication but not the tool permission, so a logged-in user denied a tool could still drive it end-to-end, including opening an interactive psql shell over the /pty socket namespace and running backup, restore, maintenance, and import/export jobs. There is no public exploit, no CISA KEV listing, and no EPSS score available, and the bypass does not grant any database privilege the user didn't already hold through their own stored connection -- this is a segregation-of-duties failure inside pgAdmin's own access-control layer, not a database privilege escalation. That said, for teams that use pgAdmin to administer Postgres instances backing pgvector stores or other AI data infrastructure, it means an internal user an admin explicitly restricted (e.g., to prevent accidental or unauthorized schema changes, bulk exports, or interactive SQL) can quietly route around that restriction. Upgrade to pgAdmin 4 9.17, where a new socket_permissions_required decorator closes the gap on every affected route and socket handler for query tool, grant wizard, schema diff, ERD, PSQL, Debugger, and the Backup/Restore/Maintenance/Import-Export blueprints; until patched, treat pgAdmin tool-permission restrictions as advisory rather than enforced and rely on database-level grants for any control that actually must hold.

Sources: NVD GitHub Advisory ATLAS

What is the risk?

CVSS 3.1 5.4 (Medium) reflects the correct framing: network-reachable, low complexity, no user interaction, but requiring low privileges (a valid, authenticated pgAdmin session) and delivering only limited confidentiality/integrity impact with no availability impact. There is no evidence of active exploitation (not in CISA KEV, no EPSS score published, no public PoC or Nuclei template), and the vulnerability class -- inconsistent authorization enforcement across a multi-route feature -- is well understood and not novel. The real risk driver is scope creep beyond the reported cases: remediation confirmed the same front-door-only gap also affected ERD, PSQL, Debugger, and the Backup/Restore/Maintenance/Import-Export blueprints, meaning the blast radius inside pgAdmin is broader than the three originally reported tools. Exposure is concentrated in SERVER-mode deployments with multiple named users and administrator-defined per-tool restrictions; single-user desktop installs of pgAdmin are not meaningfully affected since there's no segregation of duties to bypass.

How does the attack unfold?

Authenticated Low-Privilege Access
A user with a valid pgAdmin SERVER-mode login and a stored, working database connection is explicitly denied a specific tool permission (e.g., tools_query_tool, tools_grant_wizard, tools_schema_diff) by an administrator.
Front-Door Bypass
The user calls the tool's other backend routes and Socket.IO handlers directly instead of the single gated 'front door' route; those endpoints only enforce pga_login_required/socket_login_required, not the missing tool permission.
Tool Access via Existing DB Privileges
The user drives the withheld tool end-to-end over their own already-authenticated connection -- retrieving real row data, applying GRANT SQL, obtaining DDL diffs, opening an interactive psql session over /pty, or invoking backup/restore/maintenance/import-export jobs.
AML.T0036
Segregation-of-Duties Control Defeated
The organizational policy restricting that tool is circumvented without any new database privilege being granted, undermining pgAdmin's tool-level access control as an audit and change-management safeguard.

How severe is it?

CVSS 3.1
5.4 / 10
EPSS
0.2%
chance of exploitation in 30 days
Higher than 12% of all CVEs
Exploitation Status
No known exploitation
Sophistication
Moderate

What is the attack surface?

AV AC PR UI S C I A
AV Network
AC Low
PR Low
UI None
S Unchanged
C Low
I Low
A None

What should I do?

1 step
  1. Upgrade pgAdmin 4 to 9.17 or later, which adds the socket_permissions_required decorator and applies it alongside permissions_required as the outermost check on every backend route and Socket.IO handler for query tool, grant wizard, schema diff, ERD, PSQL, Debugger, and Backup/Restore/Maintenance/Import-Export. Until patched, do not rely on pgAdmin's per-tool permission system as a hard security boundary: treat any user with a stored, working database connection as capable of exercising any tool regardless of assigned pgAdmin role, and enforce real restrictions via PostgreSQL-level roles/grants (REVOKE on the underlying tables, no BACKUP/pg_dump-capable role, no superuser) instead. Separately, review any shared administrator-owned server connections for rows created via /misc/workspace/adhoc_connect_server by non-owning users -- the report notes pgAdmin can persist a new server row still owned by the administrator even when the connection attempt itself failed, which can leave orphaned or unexpected server entries under an admin's account. Audit pgAdmin server logs for 403 responses on front-door tool routes that were nonetheless followed by successful activity on the same session's other endpoints (viewdata, ACL, compare_database, /pty) as an indicator of the bypass being exercised pre-patch.

What does CISA's SSVC say?

Decision Track
Exploitation none
Automatable No
Technical Impact partial

Source: CISA Vulnrichment (SSVC v2.0). Decision based on the CISA Coordinator decision tree.

How is it classified?

Which compliance frameworks are affected?

This CVE is relevant to:

NIST AI RMF
GOVERN-1.5 - Access control and accountability mechanisms for AI system components

Frequently Asked Questions

What is CVE-2026-17350?

pgAdmin 4's per-tool permission system, introduced in 9.3 to let administrators withhold specific features (query tool, grant wizard, schema diff, PSQL, backup/restore) from individual users, only enforced that check on each tool's single "front door" route; every other backend route and Socket.IO handler behind it checked authentication but not the tool permission, so a logged-in user denied a tool could still drive it end-to-end, including opening an interactive psql shell over the /pty socket namespace and running backup, restore, maintenance, and import/export jobs. There is no public exploit, no CISA KEV listing, and no EPSS score available, and the bypass does not grant any database privilege the user didn't already hold through their own stored connection -- this is a segregation-of-duties failure inside pgAdmin's own access-control layer, not a database privilege escalation. That said, for teams that use pgAdmin to administer Postgres instances backing pgvector stores or other AI data infrastructure, it means an internal user an admin explicitly restricted (e.g., to prevent accidental or unauthorized schema changes, bulk exports, or interactive SQL) can quietly route around that restriction. Upgrade to pgAdmin 4 9.17, where a new socket_permissions_required decorator closes the gap on every affected route and socket handler for query tool, grant wizard, schema diff, ERD, PSQL, Debugger, and the Backup/Restore/Maintenance/Import-Export blueprints; until patched, treat pgAdmin tool-permission restrictions as advisory rather than enforced and rely on database-level grants for any control that actually must hold.

Is CVE-2026-17350 actively exploited?

No confirmed active exploitation of CVE-2026-17350 has been reported, but organizations should still patch proactively.

How to fix CVE-2026-17350?

Upgrade pgAdmin 4 to 9.17 or later, which adds the socket_permissions_required decorator and applies it alongside permissions_required as the outermost check on every backend route and Socket.IO handler for query tool, grant wizard, schema diff, ERD, PSQL, Debugger, and Backup/Restore/Maintenance/Import-Export. Until patched, do not rely on pgAdmin's per-tool permission system as a hard security boundary: treat any user with a stored, working database connection as capable of exercising any tool regardless of assigned pgAdmin role, and enforce real restrictions via PostgreSQL-level roles/grants (REVOKE on the underlying tables, no BACKUP/pg_dump-capable role, no superuser) instead. Separately, review any shared administrator-owned server connections for rows created via /misc/workspace/adhoc_connect_server by non-owning users -- the report notes pgAdmin can persist a new server row still owned by the administrator even when the connection attempt itself failed, which can leave orphaned or unexpected server entries under an admin's account. Audit pgAdmin server logs for 403 responses on front-door tool routes that were nonetheless followed by successful activity on the same session's other endpoints (viewdata, ACL, compare_database, /pty) as an indicator of the bypass being exercised pre-patch.

What systems are affected by CVE-2026-17350?

This vulnerability affects the following AI/ML architecture patterns: RAG pipelines, vector databases.

What is the CVSS score for CVE-2026-17350?

CVE-2026-17350 has a CVSS v3.1 base score of 5.4 (MEDIUM). The EPSS exploitation probability is 0.22%.

What is the AI security impact?

Affected AI Architectures

RAG pipelinesvector databases

MITRE ATLAS Techniques

AML.T0036 Data from Information Repositories

Compliance Controls Affected

NIST AI RMF: GOVERN-1.5

What are the technical details?

Original Advisory

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 (permissions_required) 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 pga_login_required/socket_login_required, which check authentication but not the tool permission. The reporter verified three cases against a test build: (1) a user without tools_query_tool 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 tools_grant_wizard 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 has_table_privilege(); (3) a user without tools_schema_diff 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 compare_database Socket.IO handler. The reporter also confirmed a related but distinct issue: a non-owner triggering /misc/workspace/adhoc_connect_server against an administrator-owned shared server caused pgAdmin to persist a new server row still owned by the administrator (user_id/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 permissions_required; only socket_login_required existed, checking authentication but not the tool permission. Fix adds a socket_permissions_required decorator (mirroring permissions_required, honouring the Administrator bypass, reading permissions via has_permission()) 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.

Exploitation Scenario

An organization running pgAdmin 4 in SERVER mode grants a data analyst a role with read-only query access to a Postgres database that includes a pgvector table feeding a RAG pipeline, while explicitly denying them the grant wizard and backup/restore tools to prevent privilege changes or bulk data exfiltration via dump. The analyst's browser session is already authenticated and holds a stored, working connection to that database. Instead of using the grant wizard's UI (which correctly returns 403), the analyst calls the tool's underlying ACL enumeration and GRANT-generation routes directly; because those routes only check pga_login_required and not tools_grant_wizard, they succeed, and the analyst applies a GRANT statement that expands their own or a colleague's database privileges -- verifiable server-side via has_table_privilege(). The same pattern lets a user denied the PSQL tool open an interactive psql session over the /pty Socket.IO namespace, or a user denied backup/restore trigger a full pg_dump of the vector store, all while pgAdmin's admin console shows the user as having been correctly blocked at the tool's front door.

Weaknesses (CWE)

CWE-862 — Missing Authorization: The product does not perform an authorization check when an actor attempts to access a resource or perform an action.

  • [Architecture and Design] Divide the product into anonymous, normal, privileged, and administrative areas. Reduce the attack surface by carefully mapping roles with data and functionality. Use role-based access control (RBAC) [REF-229] to enforce the roles at the appropriate boundaries. Note that this approach may not protect against horizontal authorization, i.e., it will not protect a user from attacking others with the same role.
  • [Architecture and Design] Ensure that access control checks are performed related to the business logic. These checks may be different than the access control checks that are applied to more generic resources such as files, connections, processes, memory, and database records. For example, a database may restrict access for medical records to a specific database user, but each record might only be intended to be accessible to the patient and the patient's doctor [REF-7].

Source: MITRE CWE corpus.

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N

Timeline

Published
July 31, 2026
Last Modified
August 5, 2026
First Seen
July 31, 2026

Related Vulnerabilities