暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PostgreSQL如何限制用户查看函数内容

晟数学苑 2021-06-25
816

/

  在某些情况下,我们可能只希望普通能够使用某个函数就好了,而不希望该用户能够看到函数体内部的内容,那么我们该如何控制用户的权限呢?

例如我们可以通过编写C函数来实现,例如PG的内部函数一样:

    bill@bill=>\sf+ convert
    CREATE OR REPLACE FUNCTION pg_catalog.convert(bytea, name, name)
    RETURNS bytea
    LANGUAGE internal
    STABLE PARALLEL SAFE STRICT
    1       AS $function$pg_convert$function$

      除此之外,我们可能需要利用一些能够对函数体加密的第三方插件了。那么还有没有什么办法能够直接实现呢?


      要解决这个问题前,我们需要思考两个问题:用户查看函数体内容是从哪里查的?用户使用函数又是需要什么权限?


      我们来一步步看看,pg中函数的相关信息是存在pg_proc表中的,函数体的内容存放在该表的prosrc字段中。


    创建测试函数:

      bill@bill=>create or replace function f1() returns int
      bill-# as $$
      bill$# declare
      bill$# i int:=1;
      bill$# begin
      bill$# return i;
      bill$# end;
      bill$# $$language plpgsql;
      CREATE FUNCTION

      查看函数体:

        bill@bill=>select prosrc from pg_proc where proname = 'f1';
        prosrc
        -----------
        +
        declare +
        i int:=1;+
        begin +
        return i;+
        end; +


        (1 row)

          创建普通用户,可以看到因为pg_proc的权限给了public角色,所以新建的普通用户直接就可以查询。

          bill@bill=>create user r1 ;
          CREATE ROLE
          bill@bill=>\c - r1
          You are now connected to database "bill" as user "r1".
          r1@bill=>select prosrc from pg_proc where proname = 'f1';
          prosrc
          -----------
          +
          declare +
          i int:=1;+
          begin +
          return i;+
          end; +


          (1 row)

            因此,想要限制普通用户r1查询函数体,我们首先需要将pg_proc的权限从public回收:

            bill@bill=>revoke select on pg_proc from public;
            REVOKE

              但是我们只是希望普通用户不能查看函数内容,因此还需要将除prosrc外其它字段的查询权限授回:

              bill@bill=>grant select(oid,proname,pronamespace,proowner,prolang,procost,prorows,provariadic,prosupport,prokind,prosecdef,proleakproof,proisstrict,proretset,provolatile,proparallel,pronargs,pronargdefaults,prorettype,proargtypes,proallargtypes,proargmodes,proargnames,proargdefaults,protrftypes,probin,proconfig,proacl) on pg_proc to r1;
              GRANT

              然后再使用普通用户查看:

                bill@bill=>\c - r1
                You are now connected to database "bill" as user "r1".


                r1@bill=>select prosrc from pg_proc where proname = 'f1';
                ERROR: permission denied for table pg_proc


                r1@bill=>\df f1
                List of functions
                Schema | Name | Result data type | Argument data types | Type
                --------+------+------------------+---------------------+------
                public | f1 | integer | | func
                (1 row)

                  现在我们普通用户可以使用该函数,但是查看不到该函数体的内容了,但这样就够了吗?

                  r1@bill=>\sf+ f1
                  CREATE OR REPLACE FUNCTION public.f1()
                  RETURNS integer
                  LANGUAGE plpgsql
                  1 AS $function$
                  2 declare
                  3 i int:=1;
                  4 begin
                  5 return i;
                  6 end;
                  7       $function$

                    使用\sf 仍然可以看到函数的内容,我们需要进一步看看\sf到底后台查询了哪些内容:

                    pg13@cnndr4pptliot-> psql bill bill -E
                    psql (13beta3)
                    Type "help" for help.


                    bill@bill=>\sf+ f1
                    ********* QUERY **********
                    SELECT 'f1'::pg_catalog.regproc::pg_catalog.oid
                    **************************


                    ********* QUERY **********
                    SELECT pg_catalog.pg_get_functiondef(86872)
                    **************************

                      可以看到其内部是通过调用pg_catalog.pg_get_functiondef去获取函数的定义的,因此我们还需要该权限:

                      bill@bill=>revoke execute on function pg_get_functiondef(oid) from public;
                      REVOKE

                      再次查看:

                        bill@bill=>\c - r1
                        You are now connected to database "bill" as user "r1".
                        r1@bill=>\sf+ f1
                        ERROR: permission denied for function pg_get_functiondef
                        r1@bill=>\df f1
                        List of functions
                        Schema | Name | Result data type | Argument data types | Type
                        --------+------+------------------+---------------------+------
                        public | f1 | integer | | func
                        (1 row)

                        总结:

                        最后我们总结回收一个普通用户查看函数内容的步骤:

                        1、将pg_proc的权限从public回收:

                          revoke select on pg_proc from public;

                          2、授权普通用户查询pg_proc除prosrc字段外的权限:

                            grant select(oid,proname,pronamespace,proowner,prolang,procost,prorows,provariadic,prosupport,prokind,prosecdef,proleakproof,proisstrict,proretset,provolatile,proparallel,pronargs,pronargdefaults,prorettype,proargtypes,proallargtypes,proargmodes,proargnames,proargdefaults,protrftypes,probin,proconfig,proacl) on pg_proc to r1;

                            3、回收调用pg_catalog.pg_get_functiondef的权限:

                              revoke execute on function pg_get_functiondef(oidfrom public;



                              点击下方“阅读原文”查看更多
                              ↓↓↓


                              文章转载自晟数学苑,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                              评论