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

PostgreSQL - L'utilisateur de la base de données ne devrait être autorisé qu'à appeler des fonctions

Il n'y a pas de "privilège sur SELECT ". Tout ce dont vous avez besoin est le privilège d'EXECUTE les fonctions. La fonction pertinente peut s'exécuter avec SECURITY DEFINER pour hériter de tous les privilèges du propriétaire. Pour limiter a priori une éventuelle élévation des privilèges au minimum, faites en sorte qu'un rôle démon possède les fonctions pertinentes avec uniquement les privilèges nécessaires - pas un superutilisateur !

Recette

En tant que superutilisateur ...

Créez un rôle non superutilisateur myuser .

CREATE ROLE myuser PASSWORD ...;

Créer un rôle de groupe mygroup et faites myuser membre dedans.

CREATE ROLE mygroup;
GRANT mygroup TO myuser;

Vous voudrez peut-être ajouter plus d'utilisateurs comme myuser plus tard.

N'accordez aucun privilège du tout à myuser .
Accordez-les uniquement à mygroup :

  • GRANT CONNECT ON DATABASE mydb TO mygroup;
  • GRANT USAGE ON SCHEMA public TO mygroup;
  • GRANT EXECUTE ON FUNCTION foo() TO mygroup;

Supprimer tout privilèges pour public que myuser n'aurait pas dû.

REVOKE ALL ON ALL TABLES IN SCHEMA myschema FROM public;

Il peut y en avoir plus. Je cite le manuel :

Créer un rôle de démon posséder fonctions pertinentes.

CREATE ROLE mydaemon;

Accordez uniquement les privilèges nécessaires pour exécuter ces fonctions à mydaemon , (y compris EXECUTE ON FUNCTION pour permettre l'appel d'une autre fonction). Encore une fois, vous pouvez utiliser des rôles de groupe pour regrouper des privilèges et les accorder à mydaemon

GRANT bundle1 TO mydaemon;

De plus, vous pouvez utiliser DEFAULT PRIVILEGES pour accorder automatiquement certains privilèges pour les futurs objets à un bundle ou directement au démon :

ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT SELECT ON TABLES    TO bundle1;
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT USAGE  ON SEQUENCES TO bundle1;

Cela s'applique uniquement au rôle pour lequel il est exécuté. Selon la documentation :

Pour couvrir également les objets préexistants dans le schéma (voir commentaire de rob ):

GRANT SELECT ON ALL TABLES    IN SCHEMA public TO bundle1;
GRANT USAGE  ON ALL SEQUENCES IN SCHEMA public TO bundle1;

Créer mydaemon propres fonctions pertinentes. Pourrait ressembler à ceci :

CREATE OR REPLACE FUNCTION foo()
  ...
SECURITY DEFINER SET search_path = myschema, pg_temp;

ALTER FUNCTION foo() OWNER TO mydaemon;
REVOKE EXECUTE ON FUNCTION foo() FROM public;
GRANT  EXECUTE ON FUNCTION foo() TO mydaemon;
GRANT  EXECUTE ON FUNCTION foo() TO mygroup;
-- possibly others ..

###Remarque
En raison de ce bogue dans la version actuelle 1.16.1 de pgAdmin la commande nécessaire

REVOKE EXECUTE ON FUNCTION foo() FROM public;

est manquant dans le script DDL rétroconçu. N'oubliez pas de l'ajouter lors de la recréation.
Ce bug est corrigé dans la version actuelle de pgAdmin 1.18.1.