sql >> Database >  >> RDS >> PostgreSQL

PostgreSQL-rechten en beveiliging - Het openbare schema afsluiten

Inleiding

In een vorig artikel hebben we de basisprincipes geïntroduceerd van het begrijpen van PostgreSQL-schema's, de mechanica van het maken en verwijderen, en hebben we verschillende gebruiksscenario's besproken. Dit artikel gaat dieper in op deze basisprincipes en onderzoekt het beheren van privileges met betrekking tot schema's.

Meer terminologie overbelasting

Maar er is één inleidende kwestie die opheldering behoeft. Bedenk dat we in het vorige artikel hebben stilgestaan ​​bij een mogelijk punt van verwarring in verband met overbelasting van de term 'schema'. De gespecialiseerde betekenis van die term in de context van PostgreSQL-databases verschilt van de manier waarop deze in het algemeen wordt gebruikt in relationele databasebeheersystemen. We hebben nog een soortgelijke mogelijke terminologie voor het huidige onderwerp met betrekking tot het woord "publiek".

Bij het maken van de eerste database bevat de nieuw gemaakte Postgresql-database een vooraf gedefinieerd schema met de naam "public". Het is een schema zoals elk ander, maar hetzelfde woord wordt ook gebruikt als trefwoord dat "alle gebruikers" aangeeft in contexten waar anders een echte rolnaam zou kunnen worden gebruikt, zoals ... wacht erop ... schemaprivilegebeheer . De betekenis en twee verschillende toepassingen zullen in onderstaande voorbeelden worden verduidelijkt.

Schemarechten opvragen

Voordat we dit concreet maken met voorbeeldcode om schemaprivileges toe te kennen en in te trekken, moeten we bekijken hoe schemaprivileges kunnen worden onderzocht. Met behulp van de psql-opdrachtregelinterface geven we een lijst van de schema's en bijbehorende privileges met het \dn+-commando. Voor een nieuw gemaakte sampledb-database zien we dit item voor het openbare schema:

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

De eerste twee en de vierde kolommen zijn vrij eenvoudig:zoals eerder vermeld, wordt het standaard gemaakte schema met de naam "public" weergegeven, beschreven als "standaard openbaar schema" en eigendom van de rol "postgres". (Het schema-eigendom is, tenzij anders aangegeven, ingesteld op de rol die het schema maakt.) De derde kolom met de toegangsprivileges is hier van belang. Het formaat van de privilege-informatie biedt drie items:de privilegegever, de privileges en de privilegegever in het formaat "grantee=privileges/grantor", dat wil zeggen, links van het gelijkheidsteken is de rol die de privilege(s) ontvangt, direct rechts van het gelijkheidsteken staat een groep letters die de specifieke privilege(s) specificeert, en ten slotte na de schuine streep de rol die aan privilege(s) is toegekend. Er kunnen meerdere van dergelijke privilege-informatiespecificaties zijn, gescheiden door een plusteken, aangezien privileges additief zijn.

Voor schema's zijn er twee mogelijke privileges die afzonderlijk kunnen worden verleend:U voor "GEBRUIK" en C voor "CREATE". De eerste is vereist voor een rol om database-objecten, zoals tabellen en views in het schema, op te zoeken; het laatste privilege staat een rol toe om database-objecten in het schema te maken. Er zijn andere letters voor andere privileges met betrekking tot verschillende typen database-objecten, maar voor schema's zijn alleen U en C van toepassing.

Om de bovenstaande lijst met privileges te interpreteren, vertelt de eerste specificatie ons dat de postgres-gebruiker de update heeft gekregen en zelf privileges heeft gemaakt op het openbare schema.

Merk op dat voor de tweede specificatie hierboven een lege string links van het gelijkteken verschijnt. Dit is hoe privileges die aan alle gebruikers worden verleend, door middel van het eerder genoemde PUBLIC-sleutelwoord, worden aangeduid.

Deze laatste specificatie van het verlenen van gebruik en het maken van privileges op het openbare schema aan alle gebruikers wordt door sommigen gezien als mogelijk in strijd met de algemene best practices voor beveiligingsprincipes, waarbij men er de voorkeur aan geeft te beginnen met standaard beperkte toegang, waarbij de databasebeheerder expliciet de juiste en minimaal noodzakelijke toegangsrechten. Deze liberale privileges op het openbare schema zijn met opzet in het systeem geconfigureerd voor het gemak en voor legacy-compatibiliteit.

Merk ook op dat, behalve de permissieve privilege-instellingen, het enige andere bijzondere aan het openbare schema is dat het ook wordt vermeld in het zoekpad, zoals we in het vorige artikel hebben besproken. Dit is op dezelfde manier voor het gemak:de search_path-configuratie en liberale privileges resulteren samen in een nieuwe database die bruikbaar is alsof er geen concept als schema's bestaat.

Historische achtergrond van het openbare schema

Dit compatibiliteitsprobleem stamt van ongeveer vijftien jaar geleden (vóór PostgreSQLversie 7.3, zie versie 7.3 release-opmerkingen) toen de schemafunctie geen deel uitmaakte van PostgreSQL. Door configuratie van het openbare schema met liberale privileges en de aanwezigheid van zoekpad toen schema's werden geïntroduceerd in versie 7.3, konden oudere applicaties, die niet schemabewust zijn, ongewijzigd blijven functioneren met de bijgewerkte databasefunctie.

Verder is er niets bijzonders aan het openbare schema:sommige DBA's verwijderen het als hun gebruikssituatie er geen vereiste voor stelt; anderen vergrendelen het door de standaardrechten in te trekken.

Laat me de code zien - rechten intrekken

Laten we wat code gebruiken om te illustreren en uit te breiden wat we tot nu toe hebben besproken.

Schemaprivileges worden beheerd met de GRANT- en REVOKE-opdrachten om respectievelijk privileges toe te voegen en in te trekken. We zullen enkele specifieke voorbeelden proberen om het openbare schema te vergrendelen, maar de algemene syntaxis is:

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

Laten we, als een eerste voorbeeld van een vergrendeling, het aanmaakrecht uit het openbare schema verwijderen. Merk op dat in deze voorbeelden het woord 'public' in kleine letters verwijst naar het schema en kan worden vervangen door een andere geldige schemanaam die in de database kan voorkomen. De hoofdletter "PUBLIC" is het speciale sleutelwoord dat "alle gebruikers" impliceert en kan in plaats daarvan worden vervangen door een specifieke rolnaam of een door komma's gescheiden lijst met rolnamen voor een fijnmaziger toegangscontrole.

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)

Het enige verschil in deze lijst van schemaprivileges met de eerste is de afwezigheid van de “C” in de tweede privilegespecificatie, waarmee wordt gecontroleerd of onze opdracht effectief was:andere gebruikers dan de postgres-gebruiker mogen geen tabellen, views of andere objecten meer maken in het openbare schema.

Houd er rekening mee dat de bovenstaande opdracht, waarbij de aanmaakrechten van het openbare schema worden ingetrokken, de aanbevolen oplossing is voor een recent gepubliceerde kwetsbaarheid, CVE-2018-1058, die voortvloeit uit de standaardinstelling voor bevoegdheden in het openbare schema.

Een verder niveau van vergrendeling kan inhouden dat de opzoektoegang tot het schema volledig wordt ontzegd door het gebruiksrecht te verwijderen:

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)

Aangezien alle beschikbare schemaprivileges voor gebruikers die geen eigenaar zijn zijn ingetrokken, verdwijnt de volledige tweede privilegespecificatie in de bovenstaande lijst.

Wat we deden met twee afzonderlijke commando's had beknopt kunnen worden bereikt met een enkele opdracht die alle privileges specificeerde als:

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

Daarnaast is het ook mogelijk om privileges van de schema-eigenaar in te trekken:

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)

maar dat levert niet echt iets praktisch op, aangezien de eigenaar van het schema volledige privileges behoudt voor schema's die eigendom zijn, ongeacht expliciete toewijzing, simpelweg op grond van eigendom.

De toewijzing van liberale bevoegdheden voor het openbare schema is een speciaal artefact dat wordt geassocieerd met het aanvankelijk maken van een database. Later gemaakte schema's in een bestaande database voldoen wel aan de best practice om te starten zonder toegewezen privileges. Als u bijvoorbeeld schemaprivileges onderzoekt na het maken van een nieuw schema met de naam 'private', blijkt dat het nieuwe schema geen privileges heeft:

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)
Download de whitepaper vandaag PostgreSQL-beheer en -automatisering met ClusterControlLees wat u moet weten om PostgreSQL te implementeren, bewaken, beheren en schalenDownload de whitepaper

Laat me de code zien - Privileges verlenen

De algemene vorm van het commando om privileges toe te voegen is:

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

Met dit commando kunnen we bijvoorbeeld alle rollen toestaan ​​database-objecten in het privéschema op te zoeken door het gebruiksrecht toe te voegen met

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)

Merk op hoe de UC-privileges voor de postgres-eigenaar verschijnen als de eerste specificatie, nu we andere dan de standaardprivileges aan het schema hebben toegewezen. De tweede specificatie, =U/postgres, komt overeen met het GRANT-commando dat we zojuist hebben aangeroepen als gebruiker postgres waarmee alle gebruikers gebruiksrechten krijgen (waarbij de lege string links van het gelijkteken 'alle gebruikers' aangeeft).

Een specifieke rol, bijvoorbeeld "gebruiker1" genaamd, kan zowel aanmaak- als gebruiksrechten worden toegekend aan het privéschema met:

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)

We hebben nog geen melding gemaakt van de clausule “WITH GRANT OPTION” van het algemene opdrachtformulier. Zoals het klinkt, staat deze clausule een toegekende rol toe om zelf het gespecificeerde privilege aan andere gebruikers te verlenen, en het wordt in de lijst met privileges aangegeven met sterretjes die aan het specifieke privilege zijn toegevoegd:

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)

Conclusie

Hiermee is het onderwerp voor vandaag afgerond. Onthoud echter als laatste opmerking dat we alleen de toegangsrechten voor schema's hebben besproken. Hoewel het privilege USAGE het opzoeken van database-objecten in een schema mogelijk maakt, om daadwerkelijk toegang te krijgen tot de objecten voor specifieke bewerkingen, zoals lezen, schrijven, uitvoeren, enzovoort, moet de rol ook de juiste bevoegdheden hebben voor die bewerkingen op die specifieke database-objecten.


  1. Een schemagebonden UDF maken in SQL Server

  2. Controleer of twee selecties equivalent zijn

  3. TypeError:'int' object ondersteunt geen indexering

  4. 4 manieren om een ​​lijst met schema's te krijgen in SQL Server Agent (T-SQL)