viernes, 22 de abril de 2016

El Privilegio DROP ANY TABLE es Peligroso

Estaba leyendo el blog de Laurent Schneider aquí. Según él, un usuario debe tener el privilegio DROP ANY TABLE para hacer un TRUNCATE en una tabla que pertenece a otro usuario. Esto me pareció extraño y por eso me decidí a probarlo en Oracle 11.2.0.1. Creé un usuario (USER1) que sería el dueño de una tabla:

SQL> create user user1
  2  identified by user1
  3  default tablespace users
  4  quota 10m on users
  5  /
 
User created.
 
SQL> grant
  2  create session,
  3  create table,
  4  select any dictionary
  5  to user1
  6  /
 
Grant succeeded.
 
SQL>

Luego creé un usuario (USER2) que intentaría emplear el privilegio DROP ANY TABLE para hacer un TRUNCATE en la tabla de USER1:

SQL> create user user2
  2  identified by user2
  3  /
 
User created.
 
SQL> grant
  2  create session,
  3  drop any table to user2
  4  /
 
Grant succeeded.
 
SQL>

El usuario USER1 creó una tabla con datos:

SQL> conn user1/user1
Connected.
SQL> create table tab1 as
  2  select * from dba_tables
  3  /
 
Table created.
 
SQL> grant select on tab1 to user2
  2  /
 
Grant succeeded.
 
SQL>

El usuario USER2 contó las líneas en la tabla, hizo el TRUNCATE y contó las líneas otra vez para verificar que el TRUNCATE había funcionado:

SQL> conn user2/user2
Connected.
SQL> select count(*) from user1.tab1
  2  /
 
  COUNT(*)
----------
      3192
 
SQL> truncate table user1.tab1
  2  /
 
Table truncated.
 
SQL> select count(*) from user1.tab1
  2  /
 
  COUNT(*)
----------
         0
 
SQL>

La idea de dar el privilegio DROP ANY TABLE al usuario USER2 me pareció peligroso y por eso lo revoqué:

SQL> conn / as sysdba
Connected.
SQL> revoke drop any table from user2
  2  /
 
Revoke succeeded.
 
SQL> grant create procedure to user1
  2  /
 
Grant succeeded.
 
SQL>

Entonces el usuario USER1 creó un procedimiento para hacer un TRUNCATE en su tabla:

SQL> conn user1/user1
Connected.
SQL> create procedure truncate_tab1 as
  2  begin
  3    execute immediate 'truncate table tab1';
  4  end;
  5  /
 
Procedure created.
 
SQL>

y le dio al usuario USER2 el derecho de ejecutarlo:

SQL> grant execute on truncate_tab1 to user2
  2  /
 
Grant succeeded.
 
SQL> insert into tab1 select * from dba_tables
  2  /
 
3193 rows created.
 
SQL>

Con este procedimiento el usuario USER2 podía todavía hacer un TRUNCATE en la tabla de USER1:

SQL> conn user2/user2
Connected.
SQL> select count(*) from user1.tab1
  2  /
 
  COUNT(*)
----------
      3193
 
SQL> exec user1.truncate_tab1;
 
PL/SQL procedure successfully completed.
 
SQL> select count(*) from user1.tab1
  2  /
 
  COUNT(*)
----------
         0
 
SQL> 

Pero, por supuesto, no podía borrar las tablas de los otros usuarios.

1 comentario: