代码改变世界

【PostgreSQL】PostgreSQL中public schema的权限和安全

2022-06-29 09:26  abce  阅读(7169)  评论(1编辑  收藏  举报

 

在初始数据库创建时,新创建的数据库包含一个名为“public”的预定义schema。

查看schema和schema上的特权:

mydb=# \dn+
                          List of schemas
  Name  |  Owner   |  Access privileges   |      Description       
--------+----------+----------------------+------------------------
 public | postgres | postgres=UC/postgres+| standard public schema
        |          | =UC/postgres         | 
(1 row)

mydb=# 

  

这里的第三列list of schems access privileges的格式是:

grantee=privileges/grantor

即:

权限被授予者、权限和权限授予者

可能有多个这样的权限信息规范,由加号分隔列出,因为权限是另外加的。

对于schema,有两个单独被授予的权限:

·U表示usage,用户查看数据库中在该schema下的对象,比如表、视图时,需要usage权限;

·C表示create,表示用户可以在该schema下创建数据库对象。对于不同的数据库对象,有不同的权限。但是在schema级别,只有usage(U)和create(C)权限。

上面查询结果中,第一行表示postgres被postgres授予了UC权限;第二行,等号左边是空的,表示所有用户都被授予了UC权限。

 

如果用户场景不需要public schema,可以直接删除该schema;但是,有些扩展是默认使用public schema,可以考虑收回默认的权限分配。

 

取消在public schema上的create权限:

mydb=# revoke create on schema public from public;
REVOKE
mydb=# \dn+
                          List of schemas
  Name  |  Owner   |  Access privileges   |      Description       
--------+----------+----------------------+------------------------
 public | postgres | postgres=UC/postgres+| standard public schema
        |          | =U/postgres          | 
(1 row)
​
mydb=# 

  

取消在public schema上的usage权限:

mydb=# revoke usage on schema public from public;
REVOKE
mydb=# \dn+
                          List of schemas
  Name  |  Owner   |  Access privileges   |      Description       
--------+----------+----------------------+------------------------
 public | postgres | postgres=UC/postgres | standard public schema
(1 row)
​
mydb=# 

  

同时取消create、usage权限:

mydb=# REVOKE ALL PRIVILEGES ON SCHEMA public FROM PUBLIC;
REVOKE

  

甚至可以取消schema的owner的权限:

mydb=# REVOKE ALL PRIVILEGES ON SCHEMA public FROM postgres;
REVOKE
mydb=# \dn+
                        List of schemas
  Name  |  Owner   | Access privileges |      Description       
--------+----------+-------------------+------------------------
 public | postgres |                   | standard public schema
(1 row)
​
mydb=# 

  

public schema的权限是随着创建数据库初始化就完成的,之后创建schema就需要显式授权了:

mydb=# \dn+
                          List of schemas
  Name  |  Owner   |  Access privileges   |      Description       
--------+----------+----------------------+------------------------
 public | postgres | postgres=UC/postgres | standard public schema
(1 row)
​
mydb=# create schema abce;
CREATE SCHEMA
mydb=# \dn+
                          List of schemas
  Name  |  Owner   |  Access privileges   |      Description       
--------+----------+----------------------+------------------------
 abce   | postgres |                      | 
 public | postgres | postgres=UC/postgres | standard public schema
(2 rows)
​
mydb=# 

  

因为默认的public对任何用户都是授予了usage、create权限,从安全角度要想一劳永逸地解决权限问题,可以修改模板数据库template1,因为所有数据库都是从模板数据库template1创建而来:

postgres=# c template1
You are now connected to database "template1" as user "enterprisedb".
template1=# revoke all on schema public from public;
REVOKE

  

查看所有的schema:

mydb=# SELECT schema_name FROM information_schema.schemata;
    schema_name     
--------------------
 pg_toast
 pg_catalog
 information_schema
 public
 abce
(5 rows)
​
mydb=#