summaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
authorJacob Champion2025-04-29 20:08:24 +0000
committerJacob Champion2025-04-29 20:08:24 +0000
commitd2e7d2a09d7d17656418f8c859074db690af19ec (patch)
tree3d92c5b6cfe22d4ae1eaf8a1cec444be7dc12f1e /contrib
parent45363fca6372a04e90d1c2628c3cbfe8894b811b (diff)
oauth: Disallow OAuth connections via postgres_fdw/dblink
A subsequent commit will reclassify oauth_client_secret from dispchar="" to dispchar="*", so that UIs will treat it like a secret. For our FDWs, this change will move that option from SERVER to USER MAPPING, which we need to avoid. But upon further discussion, we don't really want our FDWs to use our builtin Device Authorization flow at all, for several reasons: - the URL and code would be printed to the server logs, not sent over the client connection - tokens are not cached/refreshed, so every single connection has to be manually authorized by a user with a browser - oauth_client_secret needs to belong to the foreign server, but options on SERVER are publicly accessible - all non-superusers would need password_required=false, which is dangerous Future OAuth work can use FDWs as a motivating use case. But for now, disallow all oauth_* connection options for these two extensions. Reviewed-by: Noah Misch <[email protected]> Discussion: https://postgr.es/m/20250415191435.55.nmisch%40google.com
Diffstat (limited to 'contrib')
-rw-r--r--contrib/dblink/dblink.c7
-rw-r--r--contrib/dblink/expected/dblink.out11
-rw-r--r--contrib/dblink/sql/dblink.sql8
-rw-r--r--contrib/postgres_fdw/expected/postgres_fdw.out11
-rw-r--r--contrib/postgres_fdw/option.c7
-rw-r--r--contrib/postgres_fdw/sql/postgres_fdw.sql8
6 files changed, 52 insertions, 0 deletions
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 092f0753ff5..1b2d72c6def 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -3095,6 +3095,13 @@ is_valid_dblink_option(const PQconninfoOption *options, const char *option,
return false;
/*
+ * Disallow OAuth options for now, since the builtin flow communicates on
+ * stderr by default and can't cache tokens yet.
+ */
+ if (strncmp(opt->keyword, "oauth_", strlen("oauth_")) == 0)
+ return false;
+
+ /*
* If the option is "user" or marked secure, it should be specified only
* in USER MAPPING. Others should be specified only in SERVER.
*/
diff --git a/contrib/dblink/expected/dblink.out b/contrib/dblink/expected/dblink.out
index 7809f58d96b..c70c79574fd 100644
--- a/contrib/dblink/expected/dblink.out
+++ b/contrib/dblink/expected/dblink.out
@@ -898,6 +898,17 @@ CREATE USER MAPPING FOR public SERVER fdtest
OPTIONS (server 'localhost'); -- fail, can't specify server here
ERROR: invalid option "server"
CREATE USER MAPPING FOR public SERVER fdtest OPTIONS (user :'USER');
+-- OAuth options are not allowed in either context
+ALTER SERVER fdtest OPTIONS (ADD oauth_issuer 'https://example.com');
+ERROR: invalid option "oauth_issuer"
+ALTER SERVER fdtest OPTIONS (ADD oauth_client_id 'myID');
+ERROR: invalid option "oauth_client_id"
+ALTER USER MAPPING FOR public SERVER fdtest
+ OPTIONS (ADD oauth_issuer 'https://example.com');
+ERROR: invalid option "oauth_issuer"
+ALTER USER MAPPING FOR public SERVER fdtest
+ OPTIONS (ADD oauth_client_id 'myID');
+ERROR: invalid option "oauth_client_id"
GRANT USAGE ON FOREIGN SERVER fdtest TO regress_dblink_user;
GRANT EXECUTE ON FUNCTION dblink_connect_u(text, text) TO regress_dblink_user;
SET SESSION AUTHORIZATION regress_dblink_user;
diff --git a/contrib/dblink/sql/dblink.sql b/contrib/dblink/sql/dblink.sql
index 7870ce5d5a4..365b21036e8 100644
--- a/contrib/dblink/sql/dblink.sql
+++ b/contrib/dblink/sql/dblink.sql
@@ -469,6 +469,14 @@ CREATE USER MAPPING FOR public SERVER fdtest
OPTIONS (server 'localhost'); -- fail, can't specify server here
CREATE USER MAPPING FOR public SERVER fdtest OPTIONS (user :'USER');
+-- OAuth options are not allowed in either context
+ALTER SERVER fdtest OPTIONS (ADD oauth_issuer 'https://example.com');
+ALTER SERVER fdtest OPTIONS (ADD oauth_client_id 'myID');
+ALTER USER MAPPING FOR public SERVER fdtest
+ OPTIONS (ADD oauth_issuer 'https://example.com');
+ALTER USER MAPPING FOR public SERVER fdtest
+ OPTIONS (ADD oauth_client_id 'myID');
+
GRANT USAGE ON FOREIGN SERVER fdtest TO regress_dblink_user;
GRANT EXECUTE ON FUNCTION dblink_connect_u(text, text) TO regress_dblink_user;
diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out
index d1acee5a5fa..24ff5f70cce 100644
--- a/contrib/postgres_fdw/expected/postgres_fdw.out
+++ b/contrib/postgres_fdw/expected/postgres_fdw.out
@@ -196,6 +196,17 @@ ALTER USER MAPPING FOR public SERVER testserver1
-- permitted to check validation.
ALTER USER MAPPING FOR public SERVER testserver1
OPTIONS (ADD sslkey 'value', ADD sslcert 'value');
+-- OAuth options are not allowed in either context
+ALTER SERVER testserver1 OPTIONS (ADD oauth_issuer 'https://example.com');
+ERROR: invalid option "oauth_issuer"
+ALTER SERVER testserver1 OPTIONS (ADD oauth_client_id 'myID');
+ERROR: invalid option "oauth_client_id"
+ALTER USER MAPPING FOR public SERVER testserver1
+ OPTIONS (ADD oauth_issuer 'https://example.com');
+ERROR: invalid option "oauth_issuer"
+ALTER USER MAPPING FOR public SERVER testserver1
+ OPTIONS (ADD oauth_client_id 'myID');
+ERROR: invalid option "oauth_client_id"
ALTER FOREIGN TABLE ft1 OPTIONS (schema_name 'S 1', table_name 'T 1');
ALTER FOREIGN TABLE ft2 OPTIONS (schema_name 'S 1', table_name 'T 1');
ALTER FOREIGN TABLE ft1 ALTER COLUMN c1 OPTIONS (column_name 'C 1');
diff --git a/contrib/postgres_fdw/option.c b/contrib/postgres_fdw/option.c
index d0766f007d2..c2f936640bc 100644
--- a/contrib/postgres_fdw/option.c
+++ b/contrib/postgres_fdw/option.c
@@ -348,6 +348,13 @@ InitPgFdwOptions(void)
strcmp(lopt->keyword, "client_encoding") == 0)
continue;
+ /*
+ * Disallow OAuth options for now, since the builtin flow communicates
+ * on stderr by default and can't cache tokens yet.
+ */
+ if (strncmp(lopt->keyword, "oauth_", strlen("oauth_")) == 0)
+ continue;
+
/* We don't have to copy keyword string, as described above. */
popt->keyword = lopt->keyword;
diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql
index ea6287b03fd..1f27260bafe 100644
--- a/contrib/postgres_fdw/sql/postgres_fdw.sql
+++ b/contrib/postgres_fdw/sql/postgres_fdw.sql
@@ -213,6 +213,14 @@ ALTER USER MAPPING FOR public SERVER testserver1
ALTER USER MAPPING FOR public SERVER testserver1
OPTIONS (ADD sslkey 'value', ADD sslcert 'value');
+-- OAuth options are not allowed in either context
+ALTER SERVER testserver1 OPTIONS (ADD oauth_issuer 'https://example.com');
+ALTER SERVER testserver1 OPTIONS (ADD oauth_client_id 'myID');
+ALTER USER MAPPING FOR public SERVER testserver1
+ OPTIONS (ADD oauth_issuer 'https://example.com');
+ALTER USER MAPPING FOR public SERVER testserver1
+ OPTIONS (ADD oauth_client_id 'myID');
+
ALTER FOREIGN TABLE ft1 OPTIONS (schema_name 'S 1', table_name 'T 1');
ALTER FOREIGN TABLE ft2 OPTIONS (schema_name 'S 1', table_name 'T 1');
ALTER FOREIGN TABLE ft1 ALTER COLUMN c1 OPTIONS (column_name 'C 1');