默認情況下,PostgreSQL包含"public"模式,我們始終建議在PostgreSQL的14版本中drop掉。原因是,默認情況下,連接到數據庫的用戶都可以在public模式中創建對象。PostgreSQL 15從public模式中刪除全局寫權限。您可以查看該更改的發行說明:“移除public模式上的creation權限(Noah Misch)”。
除了“public”模式之外,還有特殊“public”角色,可以用來向系統中的每一個角色授予一個權限,但這也帶來了對默認情況下可能出現的一些情況的疑惑。默認情況下,public角色具有以下權限:
username | object_type | object_name | array
----------+-------------+--------------------+-----------------------------
public | DATABASE | postgres | {CONNECT,TEMPORARY}
public | DATABASE | template1 | {CONNECT}
public | LANGUAGE | internal | {USAGE}
public | LANGUAGE | c | {USAGE}
public | LANGUAGE | sql | {USAGE}
public | LANGUAGE | plpgsql | {USAGE}
public | SCHEMA | pg_catalog | {USAGE}
public | SCHEMA | public | {USAGE}
public | SCHEMA | information_schema | {USAGE}
(9 rows)
有一些“usuage”權限,看起來不錯,但也有針對“postgres”和“template1”數據庫的“connect”權限(如果您想知道如何從系統中獲取這些權限,那么您應該查看文檔中的“has_***”函數)。
上周,一位客戶與我們聯系,他遇到了這種情況:
postgres=# create database d;
CREATE DATABASE
postgres=# create user u with login password 'u';
CREATE ROLE
postgres=# revoke connect on database d from u;
REVOKE
簡單設置:一個數據庫,一個用戶,并從該用戶撤銷該數據庫的連接權限。該用戶是否能夠連接到數據庫?從數據庫主機外部進行簡單測試:
[email protected]:~$ psql -h 192.168.100.241 -p 5432 -U u d
psql (14.5, server 16devel)
WARNING: psql major version 14, server major version 16.
Some psql features might not work.
Type "help" for help.
d=>
即使connect權限被撤銷,仍然可以連接(當然我之前修改過pg_hba.conf)。為什么?原因是“public”角色。如果我們再次檢查該角色的權限,我們可以看到以下內容:
username | object_type | object_name | array
----------+-------------+--------------------+-----------------------------
public | DATABASE | postgres | {CONNECT,TEMPORARY}
public | DATABASE | template1 | {CONNECT}
public | DATABASE | d | {CONNECT,TEMPORARY}
public | LANGUAGE | internal | {USAGE}
public | LANGUAGE | c | {USAGE}
public | LANGUAGE | sql | {USAGE}
public | LANGUAGE | plpgsql | {USAGE}
public | SCHEMA | pg_catalog | {USAGE}
public | SCHEMA | public | {USAGE}
public | SCHEMA | information_schema | {USAGE}
(10 rows)
譯者注:默認情況下,在創建數據庫之后,允許public角色連接,即允許任何人連接。
由于“public”角色默認具有連接權限,因此所有其他用戶都可以自動使用該權限,這就是它仍然有效的原因。你應該做的是這樣的:
postgres=# revoke connect on database d from public;
REVOKE
從public角色撤銷connect后,用戶將無法再連接:
[email protected]:~$ psql -h 192.168.100.241 -p 5432 -U u d
psql: error: connection to server at "192.168.100.241", port 5432 failed: FATAL: permission denied for database "d"
DETAIL: User does not have CONNECT privilege.
請記住,授予“public”的權限對所有用戶都有效。
原文地址:https://www.dbi-services.com/blog/be-careful-with-public-in-postgresql/
原文作者:Daniel Westermann




