From 41a42035035819a58e7502d1c6211a235172193a Mon Sep 17 00:00:00 2001 From: Zsolt Parragi Date: Sat, 10 Oct 2026 09:06:55 +0000 Subject: [PATCH v3] oauth: Recheck oauth_validator_libraries during authentication The validator allowlist is only enforced while parsing pg_hba.conf. If a change to oauth_validator_libraries makes an existing oauth line invalid, the HBA reload fails and the old lines stay in use, so a removed validator keeps authenticating users. In particular, setting the list to '' doesn't refuse OAuth connections, as documented. Check the HBA line against the current setting again before loading the validator. The details, including the pg_hba.conf line, only go to the server log; the client gets the usual authentication failure. Reviewed-by: Daniel Gustafsson Reviewed-by: Shihao Zhong Discussion: https://postgr.es/m/CAN4CZFNbWXwC=s4t9Xu1kitLsQvTe-EwpVtFCjixWCHBxRTraQ@mail.gmail.com Backpatch-through: 18 --- src/backend/libpq/auth-oauth.c | 14 ++++++++++++++ src/test/modules/oauth_validator/t/001_server.pl | 11 +++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/backend/libpq/auth-oauth.c b/src/backend/libpq/auth-oauth.c index fb830065fba..3fc6097ce42 100644 --- a/src/backend/libpq/auth-oauth.c +++ b/src/backend/libpq/auth-oauth.c @@ -109,6 +109,7 @@ static void * oauth_init(Port *port, const char *selected_mech, const char *shadow_pass) { struct oauth_ctx *ctx; + char *err_msg; if (strcmp(selected_mech, OAUTHBEARER_NAME) != 0) ereport(ERROR, @@ -127,6 +128,19 @@ oauth_init(Port *port, const char *selected_mech, const char *shadow_pass) ctx->issuer = port->hba->oauth_issuer; ctx->scope = port->hba->oauth_scope; + /* + * The allowlist is otherwise only enforced when pg_hba.conf is parsed. If + * a change to oauth_validator_libraries caused the last reload to fail, + * we're still using the old HBA lines, and their validator may no longer + * be permitted. Check again before loading it. The details go to the + * server log only; the client just sees the usual authentication failure. + */ + if (!check_oauth_validator(port->hba, COMMERROR, &err_msg)) + ereport(ERROR, + errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), + errmsg("OAuth bearer authentication failed for user \"%s\"", + port->user_name)); + load_validator_library(port->hba->oauth_validator); return ctx; diff --git a/src/test/modules/oauth_validator/t/001_server.pl b/src/test/modules/oauth_validator/t/001_server.pl index 444de01ea5d..bc602b69a53 100644 --- a/src/test/modules/oauth_validator/t/001_server.pl +++ b/src/test/modules/oauth_validator/t/001_server.pl @@ -143,6 +143,17 @@ $log_start = $node->wait_for_log( $log_start); $bgconn->query_safe('SELECT 1'); +# The failed reload leaves the old HBA lines in place, but their validator is +# no longer allowed. +$node->connect_fails( + "user=test dbname=postgres oauth_issuer=$issuer oauth_client_id=f02c6361-0635", + "validator removed from oauth_validator_libraries is not used", + expected_stderr => + qr/OAuth bearer authentication failed for user "test"/, + log_like => [ + qr/parameter "oauth_validator_libraries" must be set for authentication method "oauth"/ + ]); + $node->append_conf('postgresql.conf', "oauth_validator_libraries = 'validator'"); $node->reload; -- 2.56.0