Commit 25064f5
committed
fix: enforce data isolation and harden shared servers in server mode
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 (21 audit issues) leaked owner credentials,
saved passwords to wrong records, and corrupted owner data via
SQLAlchemy session mutations.
Centralized access control:
- New server_access.py with get_server(), get_server_group(),
get_user_server_query() replacing ~20 scattered 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=current_user.id filters
Shared server isolation (addresses all 21 audit issues):
- get_shared_server_properties() expunges server from session,
suppresses passexec_cmd/post_connection_sql, overrides all 6
SSL/passfile keys, strips owner-only keys
- _is_non_owner() helper centralises 15+ inline checks
- SENSITIVE_CONN_KEYS module-level constant (DRY)
- Sanitizes connection_params on SharedServer creation
- Tunnel/DB password save branches on ownership
- change_password() checks SharedServer.password for non-owners
- clear_saved/sshtunnel_password() use get_shared_server()
- update_connection_parameter() routes to SharedServer copy
- Only owner can trigger delete_shared_server (unshare)
- SharedServer lookup uses (osid, user_id) not name (Issue 20)
- Unique constraint on SharedServer(osid, user_id) with migration
- ServerManager suppresses passexec/post_connection_sql for
non-owners at creation time
- Session restore includes shared servers
- wal_replay()/check_pgpass() use get_server()
- tunnel_port/tunnel_keep_alive copied from owner
- delete_shared_server() accepts user_id parameter
- get_shared_server() raises on None, catches IntegrityError
- create_shared_server() exception handler uses rollback
Tool/module hardening:
- All tool endpoints use get_server()
- Debugger function arguments scoped by user_id (migration)
- Background processes use Process.for_user()
- Workspace adhoc servers scoped by user_id
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)
- Fix ca00ec32581b to use raw SQL1 parent 872d5ac commit 25064f5
21 files changed
Lines changed: 920 additions & 311 deletions
File tree
- web
- migrations/versions
- pgadmin
- browser/server_groups
- servers
- databases
- schemas/views
- misc
- bgprocess
- cloud
- workspaces
- model
- tools
- debugger
- erd
- import_export
- psql
- schema_diff
- sqleditor
- user_management
- utils
- driver/psycopg3
Lines changed: 149 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
18 | | - | |
19 | | - | |
20 | 18 | | |
21 | 19 | | |
22 | 20 | | |
| |||
26 | 24 | | |
27 | 25 | | |
28 | 26 | | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
34 | 31 | | |
35 | 32 | | |
36 | 33 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| 28 | + | |
| 29 | + | |
28 | 30 | | |
29 | 31 | | |
30 | 32 | | |
| |||
286 | 288 | | |
287 | 289 | | |
288 | 290 | | |
289 | | - | |
| 291 | + | |
290 | 292 | | |
291 | 293 | | |
292 | 294 | | |
| |||
296 | 298 | | |
297 | 299 | | |
298 | 300 | | |
299 | | - | |
| 301 | + | |
| 302 | + | |
300 | 303 | | |
301 | 304 | | |
302 | 305 | | |
| |||
373 | 376 | | |
374 | 377 | | |
375 | 378 | | |
376 | | - | |
377 | | - | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
378 | 382 | | |
379 | 383 | | |
380 | 384 | | |
| |||
383 | 387 | | |
384 | 388 | | |
385 | 389 | | |
386 | | - | |
387 | | - | |
388 | | - | |
389 | | - | |
390 | | - | |
391 | | - | |
392 | | - | |
393 | | - | |
394 | | - | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
395 | 398 | | |
396 | | - | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
397 | 402 | | |
398 | 403 | | |
399 | 404 | | |
| |||
421 | 426 | | |
422 | 427 | | |
423 | 428 | | |
424 | | - | |
| 429 | + | |
425 | 430 | | |
426 | 431 | | |
427 | 432 | | |
| |||
0 commit comments