From aa27977fe21a7dfa4da4376ad66ae37cb8f0d0b5 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 20 Apr 2007 02:37:38 +0000 Subject: [PATCH] Support explicit placement of the temporary-table schema within search_path. This is needed to allow a security-definer function to set a truly secure value of search_path. Without it, a malicious user can use temporary objects to execute code with the privileges of the security-definer function. Even pushing the temp schema to the back of the search path is not quite good enough, because a function or operator at the back of the path might still capture control from one nearer the front due to having a more exact datatype match. Hence, disable searching the temp schema altogether for functions and operators. Security: CVE-2007-2138 --- doc/src/sgml/config.sgml | 16 +- doc/src/sgml/ref/create_function.sgml | 50 ++++++- doc/src/sgml/release.sgml | 188 ++++++++++++++++++----- src/backend/catalog/aclchk.c | 4 +- src/backend/catalog/namespace.c | 206 ++++++++++++++++++++++---- src/test/regress/expected/temp.out | 58 ++++++++ src/test/regress/sql/temp.sql | 33 +++++ 7 files changed, 485 insertions(+), 70 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index c5670dd906..4d4200eb36 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1,4 +1,4 @@ - + Server Configuration @@ -3405,9 +3405,17 @@ SELECT * FROM parent WHERE key = 2400; mentioned in the path then it will be searched in the specified order. If pg_catalog is not in the path then it will be searched before searching any of the path items. - It should also be noted that the temporary-table schema, - pg_temp_nnn, is implicitly searched before any of - these. + + + + Likewise, the current session's temporary-table schema, + pg_temp_nnn, is always searched if it + exists. It can be explicitly listed in the path by using the + alias pg_temp. If it is not listed in the path then + it is searched first (before even pg_catalog). However, + the temporary schema is only searched for relation (table, view, + sequence, etc) and data type names. It will never be searched for + function or operator names. diff --git a/doc/src/sgml/ref/create_function.sgml b/doc/src/sgml/ref/create_function.sgml index f4811f061a..a0e7c4490b 100644 --- a/doc/src/sgml/ref/create_function.sgml +++ b/doc/src/sgml/ref/create_function.sgml @@ -1,5 +1,5 @@ @@ -508,6 +508,54 @@ SELECT * FROM dup(42); + + Writing <literal>SECURITY DEFINER</literal> Functions Safely + + + Because a SECURITY DEFINER function is executed + with the privileges of the user that created it, care is needed to + ensure that the function cannot be misused. For security, + should be set to exclude any schemas + writable by untrusted users. This prevents + malicious users from creating objects that mask objects used by the + function. Particularly important is in this regard is the + temporary-table schema, which is searched first by default, and + is normally writable by anyone. A secure arrangement can be had + by forcing the temporary schema to be searched last. To do this, + write pg_temp as the last entry in search_path. + This function illustrates safe usage: + + + +CREATE FUNCTION check_password(uname TEXT, pass TEXT) +RETURNS BOOLEAN AS $$ +DECLARE passed BOOLEAN; + old_path TEXT; +BEGIN + -- Save old search_path; notice we must qualify current_setting + -- to ensure we invoke the right function + old_path := pg_catalog.current_setting('search_path'); + + -- Set a secure search_path: trusted schemas, then 'pg_temp'. + -- We set is_local = true so that the old value will be restored + -- in event of an error before we reach the function end. + PERFORM pg_catalog.set_config('search_path', 'admin, pg_temp', true); + + -- Do whatever secure work we came for. + SELECT (pwd = $2) INTO passed + FROM pwds + WHERE username = $1; + + -- Restore caller's search_path + PERFORM pg_catalog.set_config('search_path', old_path, true); + + RETURN passed; +END; +$$ LANGUAGE plpgsql SECURITY DEFINER; + + + + Compatibility diff --git a/doc/src/sgml/release.sgml b/doc/src/sgml/release.sgml index 9a2733fddc..fd938eb8f9 100644 --- a/doc/src/sgml/release.sgml +++ b/doc/src/sgml/release.sgml @@ -1,4 +1,4 @@ - +