sql >> Databáze >  >> RDS >> PostgreSQL

Privilegia a zabezpečení PostgreSQL – uzamčení veřejného schématu

Úvod

V předchozím článku jsme představili základy pochopení PostgreSQL schémat, mechaniku vytváření a mazání a zhodnotili několik případů použití. Tento článek rozšíří tyto základy a prozkoumá správu oprávnění souvisejících se schématy.

Další přetěžování terminologie

Je tu ale jedna předběžná záležitost, která vyžaduje objasnění. Připomeňme, že v předchozím článku jsme se pozastavili nad možným zmatkem souvisejícím s přetěžováním pojmu „schéma“. Specializovaný význam tohoto termínu v kontextu databází PostgreSQL je odlišný od toho, jak se obecně používá v systémech správy relačních databází. Pro toto téma máme další podobnou možnou terminologii související se slovem „veřejnost“.

Při počátečním vytvoření databáze obsahuje nově vytvořená databáze Postgresql předdefinované schéma s názvem „public“. Je to schéma jako každé jiné, ale stejné slovo se také používá jako klíčové slovo, které označuje „všechny uživatele“ v kontextech, kde by jinak mohl být použit skutečný název role, jako například ... čekat na to ... správa oprávnění schématu . Význam a dvě různá použití budou objasněna v příkladech níže.

Dotazování na oprávnění schématu

Než to upřesníme na příkladu kódu pro udělování a odebírání oprávnění schématu, musíme si prostudovat, jak prozkoumat oprávnění schématu. Pomocí rozhraní příkazového řádku psql vypíšeme schémata a související oprávnění příkazu \dn+. U nově vytvořené databáze sampledb vidíme tuto položku pro veřejné schéma:

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

První dva a čtvrtý sloupec jsou docela jednoduché:jak již bylo zmíněno dříve, zobrazující výchozí schéma s názvem „public“, popsané jako „standardní veřejné schéma“ a vlastněné rolí „postgres“. (Pokud není uvedeno jinak, je vlastnictví schématu nastaveno na roli, která schéma vytváří.) Zde je zajímavý třetí sloupec s přístupovými právy. Formát informací o oprávnění poskytuje tři položky:příjemce oprávnění, oprávnění a poskytovatel oprávnění ve formátu „udělovatel=privilegia/poskytovatel“, tj. vlevo od znaku rovnosti je role přijímající oprávnění, hned napravo od znaku rovnosti je skupina písmen určující konkrétní oprávnění a nakonec za lomítkem role, která byla oprávnění udělena. Těchto specifikací informací o oprávněních může být více, oddělených znaménkem plus, protože oprávnění jsou aditivní.

U schémat existují dvě možná privilegia, která mohou být udělena samostatně:U pro „USAGE“ a C pro „CREATE“. První možnost je vyžadována, aby role měla možnost vyhledávat databázové objekty, jako jsou tabulky a pohledy obsažené ve schématu; druhé oprávnění umožňuje roli vytvářet databázové objekty ve schématu. Existují další písmena pro další oprávnění týkající se různých typů databázových objektů, ale pro schémata platí pouze U a C.

Abychom tedy mohli interpretovat výše uvedený seznam oprávnění, první specifikace nám říká, že uživateli postgres byla udělena aktualizace a vytvoření oprávnění ve veřejném schématu sám.

Všimněte si, že pro druhou specifikaci výše se vlevo od znaménka rovná prázdný řetězec. Takto se označují oprávnění udělená všem uživatelům prostřednictvím výše zmíněného klíčového slova PUBLIC.

Tato druhá specifikace udělování oprávnění k používání a vytváření oprávnění ve veřejném schématu všem uživatelům je některými považována za možná v rozporu s osvědčenými postupy obecných zásad zabezpečení, kdy by bylo možné raději začít s omezeným přístupem ve výchozím nastavení, což vyžaduje, aby správce databáze výslovně udělil příslušné a minimálně nezbytná přístupová oprávnění. Tato liberální oprávnění k veřejnému schématu jsou v systému záměrně nakonfigurována pro pohodlí a pro kompatibilitu se staršími verzemi.

Všimněte si také, že kromě nastavení permisivních oprávnění je jedinou další věcí na veřejném schématu to, že je také uvedeno v search_path, jak jsme probrali v předchozím článku. To je podobné pro usnadnění:Konfigurace search_path a liberální oprávnění společně vedou k tomu, že nová databáze je použitelná, jako by neexistovala žádná taková koncepce jako schémata.

Historické pozadí veřejného schématu

Tato obava o kompatibilitu pochází z doby asi před patnácti lety (před PostgreSQLverzí 7.3, viz poznámky k verzi 7.3), kdy funkce schématu nebyla součástí PostgreSQL. Konfigurace veřejného schématu s liberálními právy a přítomností search_path, když byla schémata zavedena ve verzi 7.3, umožnila kompatibilitu starších aplikací, které nejsou schema-aware, fungovat beze změn s upgradovanou databázovou funkcí.

Jinak na veřejném schématu není nic zvláštního:někteří správci databází jej vymažou, pokud na to jejich případ použití nepředstavuje žádný požadavek; jiní jej uzamknou zrušením výchozích oprávnění.

Ukažte mi kód – zrušení oprávnění

Pojďme udělat nějaký kód pro ilustraci a rozšíření toho, o čem jsme dosud diskutovali.

Oprávnění schématu jsou spravována pomocí příkazů GRANT a REVOKE pro přidání a odebrání oprávnění. Zkusíme některé konkrétní příklady pro uzamčení veřejného schématu, ale obecná syntaxe je:

REVOKE [ GRANT OPTION FOR ]
    { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
    ON SCHEMA schema_name [, ...]
    FROM { [ GROUP ] role_name | PUBLIC } [, ...]
    [ CASCADE | RESTRICT ]

Takže jako první příklad uzamčení odeberme oprávnění k vytvoření z veřejného schématu. Všimněte si, že v těchto příkladech malé slovo „public“ odkazuje na schéma a může být nahrazeno jakýmkoli jiným platným názvem schématu, které může v databázi existovat. Velké „PUBLIC“ je speciální klíčové slovo, které implikuje „všichni uživatelé“ a místo toho by mohlo být nahrazeno konkrétním názvem role nebo seznamem názvů rolí oddělených čárkami pro jemnější řízení přístupu.

sampledb=# REVOKE CREATE ON SCHEMA public FROM PUBLIC;
REVOKE
sampledb=# \dn+
                          List of schemas
  Name  |  Owner   |  Access privileges   |      Description       
--------+----------+----------------------+------------------------
 public | postgres | postgres=UC/postgres+| standard public schema
        |          | =U/postgres          | 
(1 row)

Jediný rozdíl v tomto seznamu oprávnění schématu od prvního je nepřítomnost „C“ ve specifikaci druhého oprávnění, což ověřuje, že náš příkaz byl účinný:uživatelé jiní než uživatel postgresu již nemohou vytvářet tabulky, pohledy nebo jiné objekty v veřejné schéma.

Všimněte si, že výše uvedený příkaz revokující oprávnění k vytvoření z veřejného schématu je doporučeným zmírněním nedávno publikované chyby zabezpečení CVE-2018-1058, která vyplývá z výchozího nastavení oprávnění ve veřejném schématu.

Další úroveň uzamčení by mohla znamenat úplné odepření přístupu pro vyhledávání ke schématu odebráním oprávnění k použití:

sampledb=# REVOKE USAGE ON SCHEMA public FROM PUBLIC;
REVOKE
sampledb=# \dn+
                          List of schemas
  Name  |  Owner   |  Access privileges   |      Description       
--------+----------+----------------------+------------------------
 public | postgres | postgres=UC/postgres | standard public schema
(1 row)

Protože všechna dostupná oprávnění schématu pro uživatele, kteří nejsou vlastníky, byla odvolána, celá specifikace druhého oprávnění zmizí z výše uvedeného seznamu.

To, co jsme udělali se dvěma samostatnými příkazy, by se dalo stručně provést jediným příkazem, který specifikoval všechna oprávnění jako:

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

Navíc je také možné odejmout oprávnění vlastníkovi schématu:

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

ale to ve skutečnosti nedosahuje ničeho praktického, protože vlastník schématu si ponechává plná oprávnění k vlastněným schématům bez ohledu na explicitní přiřazení jednoduše na základě vlastnictví.

Přiřazení liberálních oprávnění pro veřejné schéma je speciální artefakt spojený s počátečním vytvořením databáze. Následně vytvořená schémata ve stávající databázi odpovídají osvědčenému postupu spuštění bez přidělených oprávnění. Například zkoumání oprávnění schématu po vytvoření nového schématu s názvem „soukromé“ ukazuje, že nové schéma nemá žádná oprávnění:

sampledb=# create schema private;
CREATE SCHEMA
sampledb=# \dn+
                          List of schemas
  Name   |  Owner   |  Access privileges   |      Description       
---------+----------+----------------------+------------------------
 private | postgres |                      | 
 public  | postgres |                      | standard public schema
(2 rows)
Stáhněte si Whitepaper Today Správa a automatizace PostgreSQL s ClusterControlZjistěte, co potřebujete vědět k nasazení, monitorování, správě a škálování PostgreSQLStáhněte si Whitepaper

Ukaž mi kód – udělování privilegií

Obecná forma příkazu pro přidání oprávnění je:

GRANT { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
    ON SCHEMA schema_name [, ...]
    TO role_specification [, ...] [ WITH GRANT OPTION ]
where role_specification can be:
  [ GROUP ] role_name
  | PUBLIC
  | CURRENT_USER
  | SESSION_USER

Pomocí tohoto příkazu můžeme například povolit všem rolím vyhledávat databázové objekty v soukromém schématu přidáním oprávnění k použití pomocí

sampledb=# GRANT USAGE ON SCHEMA private TO PUBLIC;
GRANT
sampledb=# \dn+
                          List of schemas
  Name   |  Owner   |  Access privileges   |      Description       
---------+----------+----------------------+------------------------
 private | postgres | postgres=UC/postgres+| 
         |          | =U/postgres          | 
 public  | postgres |                      | standard public schema
(2 rows)

Všimněte si, jak se oprávnění UC objevují pro vlastníka postgresu jako první specifikace, nyní, když jsme schématu přiřadili jiná než výchozí oprávnění. Druhá specifikace, =U/postgres, odpovídá příkazu GRANT, který jsme právě vyvolali jako uživatel postgres udělující oprávnění k použití všem uživatelům (kde, připomeňme, prázdný řetězec vlevo od znaménka rovná se implikuje „všichni uživatelé“).

Konkrétní roli, například pojmenované „user1“, lze soukromému schématu udělit oprávnění k vytváření a používání pomocí:

sampledb=# GRANT ALL PRIVILEGES ON SCHEMA private TO user1;
GRANT
sampledb=# \dn+
                          List of schemas
  Name   |  Owner   |  Access privileges   |      Description       
---------+----------+----------------------+------------------------
 private | postgres | postgres=UC/postgres+| 
         |          | =U/postgres         +| 
         |          | user1=UC/postgres    | 
 public  | postgres |                      | standard public schema
(2 rows)

Ještě jsme nezmínili klauzuli „WITH GRANT OPTION“ obecného příkazového formuláře. Jak to zní, tato klauzule povoluje udělené roli, která sama sobě uděluje specifikovaná oprávnění ostatním uživatelům, a je označena ve výpisu oprávnění hvězdičkami připojenými ke konkrétnímu oprávnění:

sampledb=# GRANT ALL PRIVILEGES ON SCHEMA private TO user1 WITH GRANT OPTION;
GRANT
sampledb=# \dn+
                          List of schemas
  Name   |  Owner   |  Access privileges   |      Description       
---------+----------+----------------------+------------------------
 private | postgres | postgres=UC/postgres+| 
         |          | =U/postgres         +| 
         |          | user1=U*C*/postgres  | 
 public  | postgres |                      | standard public schema
(2 rows)

Závěr

Tímto je téma pro dnešek uzavřeno. Jako poslední poznámku však nezapomeňte, že jsme diskutovali pouze o oprávněních pro přístup ke schématu. Zatímco oprávnění POUŽITÍ umožňuje vyhledávání databázových objektů ve schématu, pro skutečný přístup k objektům pro konkrétní operace, jako je čtení, zápis, provádění atd., musí mít role také příslušná oprávnění pro tyto operace s těmito konkrétními databázovými objekty.


  1. Room API - Jak získat nedávno vložené vygenerované ID entity?

  2. Jak změnit barvu pozadí formuláře v Accessu 2016

  3. Jak mohu obnovit plná oprávnění uživatele root MySQL?

  4. Oracle ekvivalentní MySQL INSERT IGNORE?