From 8ed0ecc06b33ef189e8ae853a143cfbde8c19b61 Mon Sep 17 00:00:00 2001 From: Kundan Sable Date: Fri, 4 Sep 2026 19:22:10 +0530 Subject: [PATCH] webserver auth: address round-3 review follow-ups Two non-blocking items from asheshv/pgAdmin4-cve#66's approval review: - The auth_source lockout remedy was circular for the deployments most likely to hit it: telling a locked-out admin to "sign in through another authentication source" doesn't help when AUTHENTICATION_SOURCES = ['webserver'] and there is no other source. Documented the actual way out - temporarily add 'internal' back, fix the affected users, remove it again. - A malformed WEBSERVER_REMOTE_USER (not a non-empty string) was demoted to info logging along with the client-triggered rejections in the previous round, but it's a static operator misconfiguration, not something a client varies per request - at info it would go unnoticed while every header-based login silently fails. Moved back to warning, consistent with the other config-error checks. Co-Authored-By: Claude Sonnet 5 --- docs/en_US/webserver.rst | 6 +++++- web/pgadmin/authenticate/webserver.py | 12 ++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/docs/en_US/webserver.rst b/docs/en_US/webserver.rst index 2c72dc7f2..e3e453b29 100644 --- a/docs/en_US/webserver.rst +++ b/docs/en_US/webserver.rst @@ -82,7 +82,11 @@ and modify the values for the following parameters: through Webserver authentication until you change it. To do so, sign in through another configured authentication source and, for each such user, set *Authentication source* to *webserver* on the - :ref:`User Management ` page. + :ref:`User Management ` page. If ``AUTHENTICATION_SOURCES`` + lists only *webserver*, there is no other source to sign in with - + temporarily add *internal* back to ``AUTHENTICATION_SOURCES``, sign in + with the internal administrator's password, fix the affected users' + *Authentication source*, then remove *internal* again. Master Password =============== diff --git a/web/pgadmin/authenticate/webserver.py b/web/pgadmin/authenticate/webserver.py index d85e2e367..bb8c20b9f 100644 --- a/web/pgadmin/authenticate/webserver.py +++ b/web/pgadmin/authenticate/webserver.py @@ -158,14 +158,18 @@ def _get_header_value(name): controlled source. Only returned when the operator has explicitly opted in via WEBSERVER_REMOTE_USER_FROM_HEADER, the request came from a peer listed in WEBSERVER_TRUSTED_PROXIES, and (if configured) the - shared secret matches. Every rejection here is logged at info, not - warning: an unauthenticated client can trigger any of them on every - request, and warning-level logging would let it flood the log. + shared secret matches. A client-triggered rejection here (untrusted + peer, secret mismatch) is logged at info, since an unauthenticated + client can trigger it on every request and warning-level logging + would let it flood the log. A malformed WEBSERVER_REMOTE_USER is a + static operator misconfiguration, not something a client varies per + request, and stays at warning so it doesn't go unnoticed while every + login silently fails. """ if not config.WEBSERVER_REMOTE_USER_FROM_HEADER: return None if not isinstance(name, str) or not name: - current_app.logger.info( + current_app.logger.warning( "Webserver auth: WEBSERVER_REMOTE_USER is not set to a " "non-empty name; rejecting the header-asserted identity.") return None