pgadmin4/web/pgadmin/browser/server_groups/servers
Ashesh Vashi 9a76ed80bb
fix: enforce data isolation and harden shared servers in server mode (#9830)
pgAdmin 4 in server mode had no data isolation between users — any
authenticated user could access other users' private servers,
background processes, and debugger state by guessing object IDs.
The shared server feature had 21 vulnerabilities including credential
leaks, privilege escalation via passexec_cmd, and owner data
corruption via SQLAlchemy session mutations.

Centralized access control:
- New server_access.py with get_server(), get_server_group(),
  get_user_server_query() replacing ~20 unfiltered queries
- connection_manager() raises ObjectGone (HTTP 410) in server mode
  when access is denied — fixes 155+ unguarded callers
- UserScopedMixin.for_user() on 10 models replaces scattered
  user_id filters

Shared server isolation (all 21 audit issues):
- Expunge server from session before property merge to prevent
  owner data corruption
- Suppress passexec_cmd, post_connection_sql for non-owners in
  merge, API response, and ServerManager
- Override all 6 SSL/passfile connection_params keys from
  SharedServer; strip owner-only keys; sanitize on creation
- _is_non_owner() helper centralises 15+ inline ownership checks
- SharedServer lookup uses (osid, user_id) not name
- Unique constraint on SharedServer(osid, user_id)
- Tunnel/DB password save, change_password, clear_saved_password,
  clear_sshtunnel_password all branch on ownership
- Only owner can unshare (delete_shared_server guard)
- Session restore includes shared servers
- tunnel_port/tunnel_keep_alive copied from owner, not hardcoded

Tool/module hardening:
- All tool endpoints use get_server()
- Debugger function arguments scoped by user_id
- Background processes use Process.for_user()
- Workspace adhoc servers scoped to current user

Migration (schema version 49 -> 50):
- Add user_id to debugger_function_arguments composite PK
- Add indexes on server, sharedserver, servergroup
- Add unique constraint on sharedserver(osid, user_id)
2026-04-09 18:32:59 +05:30
..
databases fix: enforce data isolation and harden shared servers in server mode (#9830) 2026-04-09 18:32:59 +05:30
directories Copyright updated for 2026 2026-01-05 13:33:45 +05:30
pgagent Copyright updated for 2026 2026-01-05 13:33:45 +05:30
pgd_replication_groups Copyright updated for 2026 2026-01-05 13:33:45 +05:30
replica_nodes Copyright updated for 2026 2026-01-05 13:33:45 +05:30
resource_groups Copyright updated for 2026 2026-01-05 13:33:45 +05:30
roles Add new options like INHERIT and SET to the Role's membership tab. #6451 2026-01-20 11:53:32 +05:30
static Ensure that the tooltip is disabled for a password cell in a dialog grid. #9552 2026-01-22 15:15:13 +05:30
tablespaces Copyright updated for 2026 2026-01-05 13:33:45 +05:30
templates Copyright updated for 2026 2026-01-05 13:33:45 +05:30
tests fix: enforce data isolation and harden shared servers in server mode (#9830) 2026-04-09 18:32:59 +05:30
__init__.py fix: enforce data isolation and harden shared servers in server mode (#9830) 2026-04-09 18:32:59 +05:30
ppas.py Copyright updated for 2026 2026-01-05 13:33:45 +05:30
types.py Copyright updated for 2026 2026-01-05 13:33:45 +05:30
utils.py fix: enforce data isolation and harden shared servers in server mode (#9830) 2026-04-09 18:32:59 +05:30