在 pg_temp 模式中调用不带前缀的函数

Flo*_*ann 3 postgresql postgresql-9.4

在 postgres 中,pg_temp模式默认位于搜索路径上。正如 Tom Lane 所解释的,出于pg_temp安全原因,默认情况下,如果没有前缀,模式中的函数是不可调用的。

但是他指出,为了在pg_temp没有前缀的情况下调用模式中的函数,您必须显式地将临时模式添加到搜索路径中。不幸的是,从 postgresql 9.4 开始,这似乎不再起作用了。

set search_path to pg_temp,public;
-- create function in the temp schema
create function test_fun() returns int as $$ select 1; $$ language sql;
-- results in "function test_fun() does not exist"
select test_fun();
-- works perfectly
select pg_temp.test_fun();
Run Code Online (Sandbox Code Playgroud)

有什么方法可以调用 pg_temp 模式中的函数而不加前缀吗?

这对于开发新功能非常方便。

Lau*_*lbe 5

看起来 Tome Lane 在这个问题上并不是 100% 精确——我从 9.2 到 9.5 进行了检查,在每一个中你都需要用 来限定该函数pg_temp。设置search_path还不够。

请参阅 PostgreSQL 提交aa27977fe21a7dfa4da4376ad66ae37cb8f0d0b5

支持在 search_path 中显式放置临时表模式。这是允许安全定义器函数设置 search_path 的真正安全值所必需的。如果没有它,恶意用户就可以使用临时对象以安全定义器函数的权限执行代码。即使将临时模式推到搜索路径的后面也不够好,因为由于具有更精确的数据类型匹配,路径后面的函数或运算符仍然可能从更靠近前面的函数或运算符捕获控制权。因此,请完全禁用在临时模式中搜索函数和运算符。

安全:CVE-2007-2138

特别参见以下方面的变化FuncnameGetCandidates

@@ -549,12 +586,16 @@ FuncnameGetCandidates(List *names, int nargs)
        }
        else
        {
-           /* Consider only procs that are in the search path */
+           /*
+            * Consider only procs that are in the search path and are not
+            * in the temp namespace.
+            */
            ListCell   *nsp;

            foreach(nsp, activeSearchPath)
            {
-               if (procform->pronamespace == lfirst_oid(nsp))
+               if (procform->pronamespace == lfirst_oid(nsp) &&
+                   procform->pronamespace != myTempNamespace)
                    break;
                pathpos++;
            }
Run Code Online (Sandbox Code Playgroud)