Analisando privilégios dentro do Oracle Database
Introdução
Um dos principais pontos voltados à segurança de uma banco de dados é o controle de quem pode acessar o que dentro do banco. Um usuário com privilégios além dos necessários para que ele execute sua função pode gerar operações indesejadas, além de que caso esta conta seja comprometida, ela tenha um alcance de impacto maior.
Neste artigo estarei abordando uma camada adicional de segurança dentro do Oracle Database, a análise de privilégios, e demonstrando como podemos fazer a análise de uso de privilégios dentro do banco de dados.
Modelo dos privilégios mínimos
Os privilégios, no banco de dados Oracle, são o que permitem a um usuário executar determinada ação dentro do banco de dados. Estes estão subdivididos em privilégios de sistema e privilégios de objetos. Os privilégios de sistema dão o direito do usuário executar uma ação administrativa ou em objetos de schema, como criar sessões no banco de dados, criar tabelas ou selecionar qualquer tabela. Já os privilégios de objeto dão o direito do usuário executar uma ação específica em um objeto específico de um schema, como selecionar o próximo valor de uma sequência específica ou inserir dados em uma tabela.
Uma das boas práticas de segurança recomendada pela Oracle, é trabalhar com o modelo dos privilégios mínimos. Nesse modelo os usuários do banco de dados tem privilégios e acesso apenas aos recursos que eles necessitam para fazer a sua função. Deste modo, caso a conta de um usuário seja comprometida, o invasor terá uma área de acesso muito menor para provocar danos.
Entretanto, é muito comum ver em diversos bancos que muitos usuários possuem privilégios desnecessários para seu uso cotidiano. Para que possamos verificar o real uso dos privilégios de um usuário, visando aplicar o modelo de privilégios mínimos, podemos utilizar a package DBMS_PRIVILEGE_CAPTURE.
DBMS_PRIVILEGE_CAPTURE
A package DBMS_PRIVILEGE_CAPTURE nos permite criar uma política de captura que registra o uso de privilégios de objeto e de sistema dos usuários, e nos permite determinar quais privilégios são utilizados e quais não são, através da análise do uso de privilégios de um usuário ou role durante um período de tempo. Após finalizada a captura, os resultados são escritos no dicionário de dados para análise. Com base nos resultados podemos revogar privilégios não utilizados, alcançando assim a melhor prática em relação ao modelo dos privilégios mínimos.
Para analisar os privilégios precisamos seguir alguns passos:
- Criar uma política de análise de privilégios: determinamos qual o tipo de coleta de uso de privilégios utilizaremos;
- Habilitar a política de análise de privilégios: iniciamos a captura dos privilégios utilizados;
- Desabilitar a política de análise de privilégios: após um determinado tempo, desabilitamos a captura de uso de privilégios;
- Geração dos resultados da análise de privilégios: neste ponto os dados coletados são escritos no dicionário de dados;
- Drop da política de análise de privilégios: podemos dropar a política criada, caso ela não seja mais utilizada;
Criando uma política
A package DBMS_PRIVILEGE_CAPTURE disponibiliza quatro constantes, que regem o comportamento da política de captura:
- G_DATABASE: analisa o uso de privilégios no banco de dados todo, exceto para o usuário SYS;
- G_ROLE: analisa o uso de privilégios de roles específicas;
- G_CONTEXT: analisa o uso de privilégios quando a condição passada na política é verdadeira;
- G_ROLE_AND_CONTEXT: analisa o uso de privilégios de roles específicas quando a condição passada na política é verdadeira;
Para criar uma política de captura de privilégios usamos a procedure CREATE_CAPTURE. Para que possamos executá-la, assim como todos as demais procedures citadas neste artigo, necessitamos ter garantida a role CAPTURE_ADMIN. Como exemplo de criação de políticas, temos:
- Captura de privilégios para o banco todo:
BEGIN DBMS_PRIVILEGE_CAPTURE.CREATE_CAPTURE( name => 'db_capture1', type => DBMS_PRIVILEGE_CAPTURE.G_DATABASE ); END; /
- Captura de privilégios das roles role_a e role_b:
BEGIN DBMS_PRIVILEGE_CAPTURE.CREATE_CAPTURE( name => 'role_capture1', type => DBMS_PRIVILEGE_CAPTURE.G_ROLE, roles => role_name_list('role_a', 'role_b') ); END; /
- Captura de privilégios do usuário HR:
BEGIN DBMS_PRIVILEGE_CAPTURE.CREATE_CAPTURE( name => 'user_capture1', type => DBMS_PRIVILEGE_CAPTURE.G_CONTEXT, condition => 'sys_context(''userenv'', ''session_user'') = ''HR''' ); END; /
- Captura de privilégios das roles_a e role_b, juntamente com o usuário HR:
BEGIN DBMS_PRIVILEGE_CAPTURE.CREATE_CAPTURE( name => 'user_role_capture1', type => DBMS_PRIVILEGE_CAPTURE.G_CONTEXT, roles => role_name_list('role_a', 'role_b'), condition => 'sys_context(''userenv'', ''session_user'') = ''HR''' ); END; /
Quando realizamos a captura de privilégios de roles, também são analisados os privilégios usados pela role que foram garantidos de maneira indireta, ou seja, um privilégio contido em outra role que foi associada à role analisada.
Podemos verificar informações referentes às políticas de análise de privilégios através da view DBA_PRIV_CAPTURES.
Habilitando a captura
Para iniciar a captura dos privilégios precisamos habilitar a política criada, através da procedure ENABLE_CAPTURE. Para isso, passamos o nome da política, e opcionalmente, um nome específico para esta execução da política, através do parâmetro “run_name”. Este último é útil para quando rodamos a mesma política mais de uma vez. Por exemplo, caso desejemos habilitar a política “user_capture1”, executamos:
BEGIN DBMS_PRIVILEGE_CAPTURE.ENABLE_CAPTURE( name => 'user_capture1', run_name => 'user_capture1_20230823'); END; /
Quando habilitamos a captura para uma política, ela recebe o valor “Y” na coluna ENABLED da view DBA_PRIV_CAPTURES.
Desabilitando a captura
Após algum tempo, desabilitamos a captura dos privilégios. Esse tempo pode variar de acordo com cada política. Por exemplo, um usuário que tenha a mesma rotina toda semana, pode ter a sua captura analisada semanalmente, ou seja, desabilitamos a política após uma semana de análise.
Para desabilitar a captura utilizamos a procedure DISBLE_CAPTURE, passando o nome por parâmetro:
EXEC DBMS_PRIVILEGE_CAPTURE.DISABLE_CAPTURE('user_capture1');
Geração dos resultados
Depois de uma política ser desabilitada, podemos gerar um relatório com base na execução da captura executada. Para gerarmos o relatório, utilizamos a procedure GENERATE_RESULT, passando o nome da política, e caso a execução foi especificada com um “run_name”, podemos repassá-lo por parâmetro também. Caso várias execuções da política tenham sido feitas e não especifiquemos “run_name”, todas as execuções serão computadas:
EXEC DBMS_PRIVILEGE_CAPTURE.DISABLE_CAPTURE('user_capture1');
Após a execução da procedure, os resultados são escritos nas views:
- DBA_USED_PRIVS: lista os privilégios usados durante a captura de privilégios;
- DBA_USED_OBJPRIVS: lista os privilégios de objeto que foram usados durante a captura de privilégios;
- DBA_USED_OBJPRIVS_PATH: lista os privilégios de objeto que foram usados durante a captura de privilégios, demonstrando o caminho de concessões indiretas de privilégios;
- DBA_USED_SYSPRIVS: lista os privilégios de sistema que foram usados durante a captura de privilégios;
- DBA_USED_SYSPRIVS_PATH: lista os privilégios de sistema que foram usados durante a captura de privilégios, demonstrando o caminho de concessões indiretas de privilégios;
- DBA_USED_USERPRIVS: lista os privilégios do usuário que foram usados durante a captura de privilégios;
- DBA_USED_USERPRIVS_PATH: lista os privilégios do usuário que foram usados durante a captura de privilégios, demonstrando o caminho de concessões indiretas de privilégios;
- DBA_USED_PUBPRIVS: lista os privilégios da role PUBLIC que foram usados durante a captura de privilégios;
- DBA_UNUSED_PRIVS: lista os privilégios que não foram usados durante a captura de privilégios;
- DBA_UNUSED_OBJPRIVS: lista os privilégios de objeto que não foram usados durante a captura de privilégios;
- DBA_UNUSED_OBJPRIVS_PATH: lista os privilégios de objeto que não foram usados durante a captura de privilégios;
- DBA_UNUSED_SYSPRIVS: lista os privilégios de sistema que não foram usados durante a captura de privilégios;
- DBA_UNUSED_SYSPRIVS_PATH: lista os privilégios de sistema que não foram usados durante a captura de privilégios, demonstrando o caminho de concessões indiretas de privilégios;
- DBA_UNUSED_USERPRIVS: lista os privilégios do usuário que não foram usados durante a captura de privilégios;
- DBA_UNUSED_USERPRIVS_PATH: lista os privilégios do usuário que foram usados durante a captura de privilégios, demonstrando o caminho de concessões indiretas de privilégios;
Com base nas informações contidas nestas views podemos determinar quais privilégios devem ser mantidos e quais devem ser revogados para os usuários ou roles analisadas, indo de encontro com o modelo dos privilégios mínimos.
Eliminando a política
De maneira opcional, podemos eliminar a política após a análise, utilizando a procedure DROP_CAPTURE:
EXEC DBMS_PRIVILEGE_CAPTURE.DROP_CAPTURE('user_capture1');
Conclusão
Limitar privilégios de usuários é mais uma das boas práticas de segurança dentro do banco de dados Oracle. Através da aplicação desse modelo de privilégios mínimos podemos evitar que usuários alterem dados que não dizem respeito a eles ou que, em caso de uma senha comprometida, o impacto dentro do banco de dados venha a ser menor do que poderia ser caso o usuário viesse a ter privilégios mais elevados.
Espero que este artigo ajude você a implementar políticas de análise de privilégios e que ajude a tornar o seu ambiente mais seguro.
Publicar comentário