sql >> Database teknologi >  >> RDS >> PostgreSQL

PostgreSQL-privilegier og sikkerhed - Låsning af det offentlige skema

Introduktion

I en tidligere artikel introducerede vi det grundlæggende i at forstå PostgreSQL-skemaer, mekanikken ved oprettelse og sletning og gennemgik adskillige use cases. Denne artikel vil udvide dette grundlæggende og udforske administrationsprivilegier relateret til skemaer.

Mere terminologioverbelastning

Men der er en foreløbig sag, der kræver afklaring. Husk på, at vi i den foregående artikel dvælede ved et muligt forvirringspunkt relateret til overbelastning af udtrykket "skema". Den specialiserede betydning af dette udtryk i forbindelse med PostgreSQL-databaser er forskellig fra, hvordan det generelt bruges i relationelle databasestyringssystemer. Vi har en anden lignende mulig terminologi kerfuffle for det aktuelle emne relateret til ordet "offentlig".

Ved den første databaseoprettelse inkluderer den nyoprettede Postgresql-database et foruddefineret skema med navnet "public". Det er et skema som ethvert andet, men det samme ord bruges også som et nøgleord, der betegner "alle brugere" i sammenhænge, ​​hvor ellers et egentligt rollenavn kan blive brugt, såsom ... vent på det ... styring af skemaprivilegier . Betydningen og to distinkte anvendelser vil blive tydeliggjort i eksemplerne nedenfor.

Forespørgsel efter skemarettigheder

Før vi gør dette konkret med eksempelkode til at give og tilbagekalde skemaprivilegier, skal vi gennemgå, hvordan man undersøger skemaprivilegier. Ved at bruge psql-kommandolinjegrænsefladen viser vi skemaerne og tilhørende privilegier med kommandoen \dn+. For en nyoprettet sampledb-database ser vi denne post for det offentlige skema:

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

De første to og den fjerde kolonne er ret ligetil:som tidligere nævnt viser det standardoprettede skema kaldet "offentlig", beskrevet som "standard offentligt skema" og ejes af rollen "postgres". (Skemaejerskabet, medmindre andet er angivet, er sat til den rolle, der opretter skemaet.) Den tredje kolonne med adgangsrettighederne er af interesse her. Formatet af privilegieoplysningerne giver tre elementer:privilegiemodtageren, privilegierne og privilegiegiveren i formatet "grantee=privileges/grantor", dvs. til venstre for lighedstegnet er den rolle, der modtager privilegiet(erne), umiddelbart til højre for lighedstegnet er en gruppe bogstaver, der specificerer det eller de særlige privilegier, og til sidst efter skråstreg den rolle, som tildelte privilegier. Der kan være flere sådanne privilegieinformationsspecifikationer, anført adskilt af et plustegn, da privilegier er additive.

For skemaer er der to mulige privilegier, som kan gives separat:U for "USAGE" og C for "CREATE". Førstnævnte er påkrævet, for at en rolle har mulighed for at slå databaseobjekter op, såsom tabeller og visninger, der er indeholdt i skemaet; sidstnævnte privilegium giver mulighed for en rolle til at oprette databaseobjekter i skemaet. Der er andre bogstaver for andre privilegier relateret til forskellige typer databaseobjekter, men for skemaer gælder kun U og C.

For således at fortolke privilegielisten ovenfor, fortæller den første specifikation os, at postgres-brugeren fik tildelt opdateringen og selv oprette privilegier på det offentlige skema.

Bemærk, at for den anden specifikation ovenfor, vises en tom streng til venstre for lighedstegnet. Sådan betegnes privilegier givet til alle brugere ved hjælp af det tidligere nævnte PUBLIC-nøgleord.

Denne sidstnævnte specifikation med at tildele brug og skabe privilegier på det offentlige skema til alle brugere anses af nogle for muligvis at være i modstrid med generelle sikkerhedsprincipper bedste praksis, hvor man måske foretrækker at starte med adgang begrænset som standard, hvilket kræver, at databaseadministratoren eksplicit giver passende og minimalt nødvendige adgangsrettigheder. Disse liberale privilegier på det offentlige skema er bevidst konfigureret i systemet som en bekvemmelighed og for ældre kompatibilitet.

Bemærk også, at bortset fra de tilladelige privilegieindstillinger, er det eneste særlige ved det offentlige skema, at det også er angivet i søgestien, som vi diskuterede i den forrige artikel. Dette er på samme måde for nemheds skyld:Search_path-konfigurationen og liberale privilegier resulterer tilsammen i, at en ny database kan bruges, som om der ikke var et koncept som skemaer.

Historisk baggrund om det offentlige skema

Denne kompatibilitetsbekymring stammer fra omkring femten år siden (før PostgreSQLversion 7.3, jf. version 7.3 release notes), hvor skemafunktionen ikke var en del af PostgreSQL. Konfiguration af det offentlige skema med liberale rettigheder og søgestiens tilstedeværelse, da skemaer blev introduceret i version 7.3, gjorde det muligt for kompatibilitet af ældre applikationer, som ikke er skemabevidste, at fungere uændret med den opgraderede databasefunktion.

Ellers er der ikke andet specielt ved det offentlige skema:nogle DBA’er sletter det, hvis deres use case ikke stiller krav om det; andre låser den ved at tilbagekalde standardrettighederne.

Vis mig koden - tilbagekaldelse af rettigheder

Lad os lave noget kode for at illustrere og udvide det, vi har diskuteret indtil nu.

Skemaprivilegier administreres med kommandoerne GRANT og REVOKE for henholdsvis at tilføje og trække privilegier tilbage. Vi vil prøve nogle specifikke eksempler på at låse det offentlige skema, men den generelle syntaks er:

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

Så lad os som et indledende lockdown-eksempel fjerne oprettelsesprivilegiet fra det offentlige skema. Bemærk, at i disse eksempler refererer det lille ord "offentlig" til skemaet og kan erstattes af et hvilket som helst andet gyldigt skemanavn, der måtte eksistere i databasen. Det store "PUBLIC" er det specielle søgeord, der indebærer "alle brugere" og kunne i stedet erstattes med et specifikt rollenavn eller kommasepareret liste over rollenavne for mere finmasket adgangskontrol.

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)

Den eneste forskel i denne liste over skemaprivilegier fra den første er fraværet af "C" i den anden privilegiespecifikation, hvilket bekræfter, at vores kommando var effektiv:andre brugere end postgres-brugeren må ikke længere oprette tabeller, visninger eller andre objekter i det offentlige skema.

Bemærk, at ovenstående kommando, der tilbagekalder oprettelsesrettigheder fra det offentlige skema, er den anbefalede afhjælpning af en nyligt offentliggjort sårbarhed, CVE-2018-1058, som opstår fra standardprivilegieindstillingen på det offentlige skema.

Et yderligere niveau af låsning kunne indebære at nægte opslagsadgang til skemaet fuldstændigt ved at fjerne brugsprivilegiet:

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)

Da alle tilgængelige skemaprivilegier for ikke-ejerbrugere er blevet tilbagekaldt, forsvinder hele den anden privilegiespecifikation i listen ovenfor.

Det, vi gjorde med to separate kommandoer, kunne have været kortfattet opnået med en enkelt kommando, der specificerede alle privilegier som:

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

Derudover er det også muligt at tilbagekalde privilegier fra skemaejeren:

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)

men det opnår ikke rigtig noget praktisk, da skemaejeren bevarer fulde privilegier til ejede skemaer uanset eksplicit tildeling blot i kraft af ejerskab.

Den liberale privilegietildeling for det offentlige skema er en speciel artefakt forbundet med den første databaseoprettelse. Efterfølgende oprettede skemaer i en eksisterende database er i overensstemmelse med den bedste praksis med at starte uden tildelte privilegier. For eksempel, undersøgelse af skemaprivilegier efter oprettelse af et nyt skema med navnet "privat" viser, at det nye skema ikke har nogen privilegier:

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 Whitepaper Today PostgreSQL Management &Automation med ClusterControlFå flere oplysninger om, hvad du skal vide for at implementere, overvåge, administrere og skalere PostgreSQLDownload Whitepaper

Vis mig koden - Give privilegier

Den generelle form for kommandoen til at tilføje privilegier er:

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

Ved at bruge denne kommando kan vi f.eks. tillade alle roller at slå databaseobjekter op i det private skema ved at tilføje brugsprivilegiet med

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)

Bemærk, hvordan UC-privilegierne vises for postgres-ejeren som den første specifikation, nu hvor vi har tildelt andre rettigheder end standardrettigheder til skemaet. Den anden specifikation, =U/postgres, svarer til den GRANT-kommando, vi lige har påkaldt som bruger postgres, der giver brugsprivilegier til alle brugere (hvor, husk, den tomme streng til venstre for lighedstegnet betyder "alle brugere").

En specifik rolle, for eksempel kaldet "bruger1", kan tildeles både oprettelses- og brugsrettigheder til det private skema med:

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)

Vi har endnu ikke nævnt "WITH GRANT OPTION"-klausulen i den generelle kommandoformular. Ligesom det lyder, tillader denne klausul en tildelt rolle beføjelsen til selv at give det specificerede privilegium til andre brugere, og det er angivet i privilegielisten med stjerner tilføjet til det specifikke privilegium:

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)

Konklusion

Dette afslutter emnet for i dag. Som en sidste bemærkning skal du dog huske, at vi kun har diskuteret skemaadgangsprivilegier. Mens USAGE-privilegiet tillader opslag af databaseobjekter i et skema, for faktisk at få adgang til objekterne til specifikke operationer, såsom læsning, skrivning, udførelse osv., skal rollen også have passende privilegier for disse operationer på de specifikke databaseobjekter.


  1. Sådan indsætter du flere rækker i en enkelt SQL-forespørgsel – Ugens interviewspørgsmål #069

  2. Hvad svarer til LISTAGG (Oracle-database) i PostgreSQL?

  3. Få tidsforskel mellem to gange i PHP

  4. Migrering af Azure Database til MySQL/MariaDB til en On-Prem Server