pgAdmin version: 9.15
Regression from: 9.14
Deployment type: Container / SERVER_MODE with OAuth2
Description
Since 9.15 (PR #9830 / CVE-2026-7813), manager.passexec is unconditionally set to None for any non-owner of a shared server in connection_manager() and _restore_connections_from_session() in web/pgadmin/utils/driver/psycopg3/__init__.py:
if config.SERVER_MODE and server_data.shared and \
server_data.user_id != current_user.id:
manager.passexec = None # PasswordExecCommand never runs
This silently breaks any container deployment that:
- Uses
PGADMIN_SERVER_JSON_FILE / servers.json with "Shared": true to pre-configure servers for all OAuth users
- Sets
"PasswordExecCommand" in the server definition to supply the shared DB user's password
- Has
PGADMIN_CONFIG_ENABLE_SERVER_PASS_EXEC_CMD=True explicitly configured by the system administrator
The ENABLE_SERVER_PASS_EXEC_CMD config flag is now meaningless for shared servers — it is checked on startup/UI but the suppression in connection_manager fires regardless, with no log message or error surfaced to the user. The connection silently has no password.
Expected behaviour
When ENABLE_SERVER_PASS_EXEC_CMD=True is explicitly set by the system administrator, PasswordExecCommand should be honoured for shared-server non-owners. The system admin has consciously opted into this feature and is responsible for the command's content — the privilege-escalation concern (malicious owner targeting users) does not apply when the admin and the server owner are the same entity (i.e., the deployment administrator).
A reasonable middle ground: honour passexec_cmd from the SharedServer record (already added as a column in #9835) for non-owners, while still blocking inheritance from the owner's Server record. Currently _owner_only_fields prevents non-owners from ever setting passexec_cmd on their SharedServer via the API, and create_shared_server() seeds it as None, making the new column unreachable.
Steps to reproduce
- Deploy pgAdmin container with:
PGADMIN_CONFIG_SERVER_MODE=True
PGADMIN_CONFIG_ENABLE_SERVER_PASS_EXEC_CMD=True
PGADMIN_SERVER_JSON_FILE=/path/to/servers.json
servers.json contains a server entry with "Shared": true and "PasswordExecCommand": "<cmd>"
- Log in as any non-admin OAuth user
- Attempt to connect to the shared server
Result: The exec command is never run; the connection has no password and fails (or prompts interactively).
Expected: The exec command runs and supplies the password, as it did in 9.14.
Relevant source locations
web/pgadmin/utils/driver/psycopg3/__init__.py — connection_manager() and _restore_connections_from_session(): unconditional manager.passexec = None for non-owners
web/pgadmin/browser/server_groups/servers/__init__.py — _set_valid_attr_value(): _owner_only_fields blocks non-owners from setting passexec_cmd on their SharedServer
web/pgadmin/browser/server_groups/servers/__init__.py — create_shared_server(): seeds passexec_cmd=None with no path to set it legitimately
pgAdmin version: 9.15
Regression from: 9.14
Deployment type: Container / SERVER_MODE with OAuth2
Description
Since 9.15 (PR #9830 / CVE-2026-7813),
manager.passexecis unconditionally set toNonefor any non-owner of a shared server inconnection_manager()and_restore_connections_from_session()inweb/pgadmin/utils/driver/psycopg3/__init__.py:This silently breaks any container deployment that:
PGADMIN_SERVER_JSON_FILE/servers.jsonwith"Shared": trueto pre-configure servers for all OAuth users"PasswordExecCommand"in the server definition to supply the shared DB user's passwordPGADMIN_CONFIG_ENABLE_SERVER_PASS_EXEC_CMD=Trueexplicitly configured by the system administratorThe
ENABLE_SERVER_PASS_EXEC_CMDconfig flag is now meaningless for shared servers — it is checked on startup/UI but the suppression inconnection_managerfires regardless, with no log message or error surfaced to the user. The connection silently has no password.Expected behaviour
When
ENABLE_SERVER_PASS_EXEC_CMD=Trueis explicitly set by the system administrator,PasswordExecCommandshould be honoured for shared-server non-owners. The system admin has consciously opted into this feature and is responsible for the command's content — the privilege-escalation concern (malicious owner targeting users) does not apply when the admin and the server owner are the same entity (i.e., the deployment administrator).A reasonable middle ground: honour
passexec_cmdfrom the SharedServer record (already added as a column in #9835) for non-owners, while still blocking inheritance from the owner'sServerrecord. Currently_owner_only_fieldsprevents non-owners from ever settingpassexec_cmdon their SharedServer via the API, andcreate_shared_server()seeds it asNone, making the new column unreachable.Steps to reproduce
servers.jsoncontains a server entry with"Shared": trueand"PasswordExecCommand": "<cmd>"Result: The exec command is never run; the connection has no password and fails (or prompts interactively).
Expected: The exec command runs and supplies the password, as it did in 9.14.
Relevant source locations
web/pgadmin/utils/driver/psycopg3/__init__.py—connection_manager()and_restore_connections_from_session(): unconditionalmanager.passexec = Nonefor non-ownersweb/pgadmin/browser/server_groups/servers/__init__.py—_set_valid_attr_value():_owner_only_fieldsblocks non-owners from settingpassexec_cmdon their SharedServerweb/pgadmin/browser/server_groups/servers/__init__.py—create_shared_server(): seedspassexec_cmd=Nonewith no path to set it legitimately