PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Privilèges et sécurité PostgreSQL - Verrouillage du schéma public

Présentation

Dans un article précédent, nous avons présenté les bases de la compréhension des schémas PostgreSQL, les mécanismes de création et de suppression, et passé en revue plusieurs cas d'utilisation. Cet article approfondira ces bases et explorera la gestion des privilèges liés aux schémas.

Plus de surcharge de terminologie

Mais il y a une question préliminaire qui nécessite des éclaircissements. Rappelons que dans l'article précédent, nous nous sommes attardés sur un éventuel point de confusion lié à la surcharge du terme « schéma ». La signification spécialisée de ce terme dans le contexte des bases de données PostgreSQL est distincte de la façon dont il est généralement utilisé dans les systèmes de gestion de bases de données relationnelles. Nous avons un autre cafouillage terminologique similaire pour le présent sujet lié au mot « public ».

Lors de la création initiale de la base de données, la base de données Postgresql nouvellement créée inclut un schéma prédéfini nommé « public ». C'est un schéma comme un autre, mais le même mot est également utilisé comme mot-clé qui désigne "tous les utilisateurs" dans des contextes où, sinon, un nom de rôle réel pourrait être utilisé, comme ... attendez-le ... gestion des privilèges du schéma . La signification et les deux utilisations distinctes seront clarifiées dans les exemples ci-dessous.

Interroger les privilèges du schéma

Avant de concrétiser cela avec un exemple de code pour accorder et révoquer des privilèges de schéma, nous devons revoir comment examiner les privilèges de schéma. En utilisant l'interface de ligne de commande psql, nous listons les schémas et les privilèges associés avec la commande \dn+. Pour une base de données sampledb nouvellement créée, nous voyons cette entrée pour le schéma public :

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

Les deux premières et la quatrième colonnes sont assez simples :comme mentionné précédemment, elles montrent le schéma créé par défaut nommé "public", décrit comme "schéma public standard" et détenu par le rôle "postgres". (La propriété du schéma, sauf indication contraire, est définie sur le rôle qui crée le schéma.) Cette troisième colonne répertoriant les privilèges d'accès est intéressante ici. Le format des informations de privilège fournit trois éléments :le bénéficiaire du privilège, les privilèges et le concédant du privilège au format "bénéficiaire=privilèges/concédant", c'est-à-dire qu'à gauche du signe d'égalité se trouve le rôle recevant le(s) privilège(s), immédiatement à droite du signe d'égalité se trouve un groupe de lettres spécifiant le(s) privilège(s) particulier(s), et enfin après la barre oblique le rôle accordé au(x) privilège(s). Il peut y avoir plusieurs spécifications d'informations sur les privilèges, répertoriées séparées par un signe plus puisque les privilèges s'additionnent.

Pour les schémas, il existe deux privilèges possibles qui peuvent être accordés séparément :U pour « USAGE » et C pour « CREATE ». Le premier est requis pour qu'un rôle puisse rechercher des objets de base de données tels que des tables et des vues contenues dans le schéma ; ce dernier privilège permet à un rôle de créer des objets de base de données dans le schéma. Il existe d'autres lettres pour d'autres privilèges relatifs à différents types d'objets de base de données, mais pour les schémas, seuls U et C s'appliquent.

Ainsi, pour interpréter la liste des privilèges ci-dessus, la première spécification nous indique que l'utilisateur postgres s'est vu accorder les privilèges de mise à jour et de création par lui-même sur le schéma public.

Notez que pour la deuxième spécification ci-dessus, une chaîne vide apparaît à gauche du signe égal. C'est ainsi que les privilèges accordés à tous les utilisateurs, au moyen du mot clé PUBLIC mentionné précédemment, sont notés.

Cette dernière spécification d'accorder des privilèges d'utilisation et de création sur le schéma public à tous les utilisateurs est considérée par certains comme peut-être contraire aux meilleures pratiques des principes généraux de sécurité, où l'on pourrait préférer commencer avec un accès restreint par défaut, obligeant l'administrateur de la base de données à accorder explicitement les droits appropriés. et les privilèges d'accès minimum nécessaires. Ces privilèges libéraux sur le schéma public sont configurés à dessein dans le système pour plus de commodité et pour la compatibilité héritée.

Notez également qu'à l'exception des paramètres de privilèges permissifs, la seule autre particularité du schéma public est qu'il est également répertorié dans le search_path, comme nous l'avons vu dans l'article précédent. Ceci est similaire pour plus de commodité :la configuration search_path et les privilèges libéraux permettent d'utiliser une nouvelle base de données comme s'il n'existait pas de concept tel que les schémas.

Contexte historique sur le régime public

Ce problème de compatibilité remonte à une quinzaine d'années (avant la version 7.3 de PostgreSQL, cf. notes de version de la version 7.3) lorsque la fonctionnalité de schéma ne faisait pas partie de PostgreSQL. La configuration du schéma public avec des privilèges libéraux et la présence de search_path lorsque les schémas ont été introduits dans la version 7.3 ont permis à la compatibilité des applications plus anciennes, qui ne reconnaissent pas le schéma, de fonctionner sans modification avec la fonctionnalité de base de données mise à niveau.

Sinon, il n'y a rien d'autre de particulièrement spécial à propos du schéma public :certains DBA le suppriment si leur cas d'utilisation ne présente aucune exigence ; d'autres le verrouillent en révoquant les privilèges par défaut.

Montrez-moi le code - Révocation des privilèges

Faisons un peu de code pour illustrer et développer ce dont nous avons discuté jusqu'à présent.

Les privilèges du schéma sont gérés avec les commandes GRANT et REVOKE pour respectivement ajouter et retirer des privilèges. Nous allons essayer quelques exemples spécifiques pour verrouiller le schéma public, mais la syntaxe générale est :

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

Donc, comme exemple de verrouillage initial, supprimons le privilège de création du schéma public. Notez que dans ces exemples, le mot « public » en minuscules fait référence au schéma et peut être remplacé par tout autre nom de schéma valide pouvant exister dans la base de données. Le "PUBLIC" majuscule est le mot-clé spécial qui implique "tous les utilisateurs" et pourrait à la place être remplacé par un nom de rôle spécifique ou une liste de noms de rôles séparés par des virgules pour un contrôle d'accès plus précis.

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)

La seule différence entre cette liste de privilèges de schéma et la première est l'absence du "C" dans la deuxième spécification de privilège, vérifiant que notre commande était efficace :les utilisateurs autres que l'utilisateur postgres ne peuvent plus créer de tables, de vues ou d'autres objets dans le schéma public.

Notez que la commande ci-dessus révoquant les privilèges de création du schéma public est l'atténuation recommandée pour une vulnérabilité récemment publiée, CVE-2018-1058, qui découle du paramètre de privilège par défaut sur le schéma public.

Un autre niveau de verrouillage pourrait impliquer de refuser entièrement l'accès de recherche au schéma en supprimant le privilège d'utilisation :

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)

Étant donné que tous les privilèges de schéma disponibles pour les utilisateurs non propriétaires ont été révoqués, l'intégralité de la deuxième spécification de privilège disparaît dans la liste ci-dessus.

Ce que nous avons fait avec deux commandes distinctes aurait pu être accompli succinctement avec une seule commande spécifiant tous les privilèges comme :

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

De plus, il est également possible de révoquer les privilèges du propriétaire du schéma :

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)

mais cela n'accomplit vraiment rien de pratique, car le propriétaire du schéma conserve tous les privilèges sur les schémas possédés indépendamment de l'affectation explicite simplement en vertu de la propriété.

L'attribution de privilège libéral pour le schéma public est un artefact spécial associé à la création initiale de la base de données. Les schémas créés ultérieurement dans une base de données existante sont conformes à la meilleure pratique consistant à démarrer sans privilèges attribués. Par exemple, l'examen des privilèges du schéma après la création d'un nouveau schéma nommé "privé" montre que le nouveau schéma n'a aucun privilège :

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)
Téléchargez le livre blanc aujourd'hui PostgreSQL Management &Automation with ClusterControlDécouvrez ce que vous devez savoir pour déployer, surveiller, gérer et faire évoluer PostgreSQLTélécharger le livre blanc

Montrez-moi le code – Octroi de privilèges

La forme générale de la commande pour ajouter des privilèges est :

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

En utilisant cette commande, nous pouvons, par exemple, autoriser tous les rôles à rechercher des objets de base de données dans le schéma privé en ajoutant le privilège d'utilisation avec

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)

Notez comment les privilèges UC apparaissent pour le propriétaire postgres en tant que première spécification, maintenant que nous avons attribué des privilèges autres que ceux par défaut au schéma. La deuxième spécification, =U/postgres, correspond à la commande GRANT que nous venons d'invoquer en tant qu'utilisateur postgres accordant le privilège d'utilisation à tous les utilisateurs (où, rappelez-vous, la chaîne vide à gauche du signe égal implique "tous les utilisateurs").

Un rôle spécifique, nommé "utilisateur1" par exemple, peut se voir accorder à la fois des privilèges de création et d'utilisation sur le schéma privé avec :

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)

Nous n'avons pas encore mentionné la clause "WITH GRANT OPTION" du formulaire de commande général. Tout comme il semble, cette clause permet à un rôle accordé le pouvoir d'accorder lui-même le privilège spécifié à d'autres utilisateurs, et il est indiqué dans la liste des privilèges par des astérisques ajoutés au privilège spécifique :

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)

Conclusion

Ceci conclut le sujet d'aujourd'hui. Pour finir, souvenez-vous que nous n'avons discuté que des privilèges d'accès au schéma. Alors que le privilège USAGE permet la recherche d'objets de base de données dans un schéma, pour accéder réellement aux objets pour des opérations spécifiques, telles que la lecture, l'écriture, l'exécution, etc., le rôle doit également disposer des privilèges appropriés pour ces opérations sur ces objets de base de données spécifiques.