Voir le flux RSS

Fabien Celaia

Oracle : sécurité, ANY et schémas

Noter ce billet
par , 22/06/2018 à 09h29 (1794 Affichages)
Problématique

Oracle souffre d'une grosse faiblesse fonctionnelle au niveau des permissions DDL (Data Definition Language) que l'on peut donner.
  1. Il est possible de donner des droits de créer des objets à un utilisateur donné (user) dans son propre schéma (owner) avec les droits spécifiques CREATE TABLE, CREATE PROCEDURE, ... ou des droits plus génériques de type RESOURCE. Dans ce cas, l'utilisateur ne peut influer que sur SON propre schéma
  2. Si l'on souhaite qu'un utilisateur obtienne ces droits sur une autre schéma, il faut lui donner un droit ANY


Dans des environnements multi-applicatifs où la sécurité est gérée par affinité de schémas, cela pose un réel problème en terme de sécurité puisque le droit ANY donne la permissions associée à TOUS les schémas de la base de données.

Depuis la version 12, Oracle tente de pallier à cette carence sécuritaire par une "pirouette" : les bases multitenants. Il s'agit-là d'un bricolage : il part de la fausse idée qu'un ensemble de schémas interconnecté sera forcément regroupé dans une base... et que dans le cas contraire, on se débrouillera avec des permissions globales des fameux utilisateurs C#... on reporte donc le problème à un autre niveau, sans le résoudre... et l'option multitenant est onéreuse... pour ne pas dire dispendieuse

Solution gratuite

Il existe un autre moyen de contourner ce problème, toujours en mode bricolage : l'utilisation d'un déclencheur sur DDL.
Le concept est malgré tout particulier :
  • on donne un droit trop étendu (ANY)
  • un bride ce droit via le déclencheur


Il reste à opter pour l'option permissive ou restrictive

  • permissive : on autorise tout ce que le ANY autorise, hormis pour ce que l'on bride en spécifiant les droits qu'on ne veut pas donner dans une table spécifique
  • restrictive : on n'autorise que ce que l'on spécifie dans la table spécifique


La table spécifique en question aurait ce type de structure

Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
create table ddlperm
(username varchar2(128) not null, /*L'utilisateur que l'on veut traiter*/
schemas varchar2(128) not null,  /*le schéma spécifique dans lequel il pourra utiliser son droit */
perm varchar2(100) ,  /*le droit en question (ALTER, CREATE, DROP, TRUNCATE, ....) */
objtype varchar2(23) not null /* le type d'objet traité (TABLE, PROCEDURE, VIEW, TRIGGER, PACKAGE...)*/
) ;
grant select on ddlperm to public;

Un exemple de trigger en mode restrictif, mais je me focaliserai ensuite sur le mode permissif, plus aisé à gérer.

Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
create  trigger DDL_Trg before DDL ON DATABASE
declare val int ;
BEGIN
select count(*) into val 
from vsdba.ddlperm 
where username = user 
and schemas =  ora_dict_obj_owner
and perm = ora_sysevent
and objtype=ora_dict_obj_type ;
 
if val=0 then
    RAISE_APPLICATION_ERROR ( num => -20000,  msg => 'Permission DDL manquante : event='||ora_sysevent|| ',user='||user ||',owner='||ora_dict_obj_owner||',type='||ora_dict_obj_type);
end if ;
end ;
/

Attention dans ce cas : vous vous rendrez bien vite compte qu'il faut traiter les droits de façon fine... par exemple, un DROP TABLE Oracle fait en fait un DROP + ALTER TABLE... d'où mon intérêt pour le mode plus permissif.

En mode permissif , on laisse donc le droit ANY faire son effet au sens large et on interdit ce que l'on souhaite absolument bloquer.

Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
create trigger DDL_Trg before DDL ON DATABASE
declare val int ;
BEGIN
select count(*) into val 
from vsdba.ddlperm 
where username = user 
and schemas =  ora_dict_obj_owner
and perm = ora_sysevent
and objtype=ora_dict_obj_type ;
 
if val>0 then
    RAISE_APPLICATION_ERROR ( num => -20000,  msg => 'Permission DDL bridée : event='||ora_sysevent|| ',user='||user ||',owner='||ora_dict_obj_owner||',type='||ora_dict_obj_type);
end if ;
end ;

Vous l'aurez compris : il vous faut choisir l'une ou l'autre méthode, mais ne pas mixer les deux...

Vous pouvez bien entendu vous inspirer de ces codes et aller plus ou moins loin.
  • en ne restant qu'au stade du contrôle du schéma, en supprimant la gestion des colonnes PERM et OBJTYPE
  • en ajoutant ora_dict_obect pour mettre la granularité au niveau de l'objet


Granularité au niveau du schéma

Voici la version simpliste au niveau du schéma, en mode restrictif:

Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
create table ddlperm
(username varchar2(128) not null, /*L'utilisateur que l'on veut traiter*/
schemas varchar2(128) not null  /*le schéma spécifique dans lequel il pourra utiliser son droit */
) ;
grant select on ddlperm to public; 
 
insert into ddlperm ('user1','user2') ;
grant create any table to user1 ;
commit ;
 
create trigger DDL_Trg before DDL ON DATABASE
declare val int ;
BEGIN
select count(*) into val 
from vsdba.ddlperm 
where username = user 
and schemas =  ora_dict_obj_owner;
 
if val=0 then
     RAISE_APPLICATION_ERROR ( num => -20000,  msg => 'Droit '||ora_sysevent|| ' bridé sur le schéma '||ora_dict_obj_owner);
end if ;
end ;
/

On donne donc le droit à user1 de créer une table n'importe où via le droit ANY, mais on le limite au schéma user2 via notre trigger, si le couple {utilsiateur, schéma} ne se trouve pas dans la table ddlperm.

Envoyer le billet « Oracle : sécurité, ANY et schémas » dans le blog Viadeo Envoyer le billet « Oracle : sécurité, ANY et schémas » dans le blog Twitter Envoyer le billet « Oracle : sécurité, ANY et schémas » dans le blog Google Envoyer le billet « Oracle : sécurité, ANY et schémas » dans le blog Facebook Envoyer le billet « Oracle : sécurité, ANY et schémas » dans le blog Digg Envoyer le billet « Oracle : sécurité, ANY et schémas » dans le blog Delicious Envoyer le billet « Oracle : sécurité, ANY et schémas » dans le blog MySpace Envoyer le billet « Oracle : sécurité, ANY et schémas » dans le blog Yahoo

Mis à jour 22/06/2018 à 10h19 par Fabien Celaia

Catégories
SGBD , Oracle

Commentaires