CVE-2026-17350: pgAdmin: broken access control bypasses tool permissions
MEDIUMpgAdmin 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.
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?
How severe is it?
What is the attack surface?
What should I do?
1 step-
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?
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:
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
MITRE ATLAS Techniques
AML.T0036 Data from Information Repositories Compliance Controls Affected
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 References
- github.com/pgadmin-org/pgadmin4/commit/461c3afba92baad37c70a6fbd52d205d13a9de53
- github.com/pgadmin-org/pgadmin4/commit/64a9cdbd6a240a962144f84418beaf9e66419779
- github.com/pgadmin-org/pgadmin4/commit/ba1984718ad703011740ad48cb9b82402b89cc2c
- github.com/pgadmin-org/pgadmin4/commit/d36bd8dc96812c716664feac533d240544e70adc
- github.com/pgadmin-org/pgadmin4/issues/10190
Timeline
Related Vulnerabilities
CVE-2025-5120 10.0 smolagents: sandbox escape enables unauthenticated RCE
Same attack type: Code Execution CVE-2025-59528 10.0 Flowise: Unauthenticated RCE via MCP config injection
Same attack type: Code Execution CVE-2025-2828 10.0 LangChain RequestsToolkit: SSRF exposes cloud metadata
Same attack type: Auth Bypass CVE-2025-53767 10.0 Azure OpenAI: SSRF EoP, no auth required (CVSS 10)
Same attack type: Auth Bypass CVE-2024-2912 10.0 BentoML: RCE via insecure deserialization (CVSS 10)
Same attack type: Code Execution