Oracle Data Redaction

O Oracle Data Redaction(ODC), é uma nova feature do Oracle 12c, que também foi disponibilizada no Oracle 11.2.0.4, que permite a aplicação de políticas de mascaramento de dados sigilosos ou sensíveis, controlando, por exemplo, quem pode ver determinada informação e como esta será exibida para o usuário, definindo também quem pode e quem não pode visualizar o conteúdo real dos campos, usando expressões nas políticas de mascaramento. O Oracle Data Redaction é uma feature fantástica que nos permite implementar níveis de proteção de acordo com as necessidades do negócio.


É importante dizer que o mascaramento dos dados é realizado em tempo de execução, ou seja, os dados armazenados em disco continuam intactos e joins entre tabelas usando os campos mascarados também não são afetados, pois o mascaramento é feito ao final do processamento da consulta.

O Oracle Data Redaction não pode ser feito para os tipos de dados que não são suportados como: LONG e LONG RAW, INTERVAL, BFILE, ROWID e UROWID e TYPES.

Para criar políticas de mascaramento o usuário precisar ter permissão de EXECUTE na package DBMS_REDACT.

Os tipos de politicas que podemos implementar são:

Full redaction: Esse é o tipo padrão caso não seja definido o parâmetro function_type ao criar a política. Utilizando este tipo de política, para as colunas do tipo number, todas as informações serão exibidas como zero, já as colunas do tipo texto são exibidas como espaço em branco e campos do tipo data/hora serão exibidos como 01/JAN/01.

Partial redaction: Neste tipo de política, somente uma parte do conteúdo do campo é mascarado e deve ter um tamanho fixo. Para mascarar campos de tamanho variável é necessário usar uma expressão regular.
É possível definir a posição inicial dentro do campo e quantos caracteres devem ser mascarados a partir da posição inicial. É possível definir também qual caracter irá substituir o caracter original.

Expressão regular: Com este tipo de política é possível usar expressão regular para mascarar dados de campos do tipo varchar2, onde o conteúdo do campo tem um tamanho variável como endereços de e-mail;

Random redaction: Já para este tipo de política, todo o conteúdo do campo é mascarado de maneira aleatória e com valores diferentes a cada execução da consulta.

1 - Exemplo: Política - Full Redaction

Criamos uma tabela de teste que irá conter o salário dos funcionários e aproveitamos para realizar alguns lançamentos:

SQL> Create table tb_salario(nome varchar2(30), salario number(10));
Table created.

SQL> insert into tb_salario values ('Ricardo',1000);
1 row created.

SQL> insert into tb_salario values ('Jose',1500);
1 row created.

SQL> insert into tb_salario values ('Carlos',3000);
1 row created.

SQL> commit;
Commit complete.

Note que quando consultamos os funcionários na tabela, conseguimos visualizar o salário de cada um sem maiores problemas:

SQL> select * from tb_salario;

NOME                              SALARIO
----------------------------- ----------
Ricardo                              1000
Jose                                 1500
Carlos                               3000

Vamos implementar a política Full Redaction utilizando o package dbms_redact, onde passamos alguns parâmetros importantes como: esquema, nome da tabela, a coluna que queremos aplicar a política de mascaramento e o tipo da política aplicada:

SQL> BEGIN
    DBMS_REDACT.ADD_POLICY(
     object_schema => 'TESTE',
     object_name => 'TB_SALARIO',
     column_name => 'SALARIO',
     policy_name => 'redact_saldo_full',
     function_type => DBMS_REDACT.FULL,
     expression => '1=1');
END;
/  

PL/SQL procedure successfully completed.

Agora quando consultarmos as informações dos funcionários novamente, a coluna salário será mascarada:

SQL> select * from tb_salario;

NOME                              SALARIO
------------------------------ ----------
Ricardo                                 0
Jose                                    0
Carlos                                  0
SQL>

O valor padrão “0” que foi utilizado para mascarar os dados sensíveis pode ser alterado usando a procedure DBMS_REDACT.UPDATE_FULL_REDACTION_VALUES

2 - Exemplo: Política - Partial Redaction

Vamos a um exemplo para criar uma política de mascaramento parcial dos dados, utilizando o Partial Redaction.
Criamos uma tabela de funcionários que armazenaremos o nome e o cpf do funcionário.

Aproveitamos e inserimos alguns funcionários:

SQL> create table tb_funcionarios(funcionario varchar2(30), cpf varchar2(15));
Table created.

SQL> insert into tb_funcionarios values('Maria','123.234.345-09');
1 row created.

SQL> insert into tb_funcionarios values('Renan','234.122.899-08');
1 row created.

SQL> insert into tb_funcionarios values('Lucas','566.989.977-10');
1 row created.

SQL> commit;
Commit complete.

Note que ao consultar os funcionários na tabela conseguimos visualizar o cpf que poderia ser um dado sensível pela regra de negócio:

SQL> select * from tb_funcionarios;

FUNCIONARIO                    CPF
------------------------------ ---------------
Maria                          123.234.345-09
Renan                          234.122.899-08
Lucas                          566.989.977-10

Vamos implementar agora a política Partial Redaction, passando como parâmetro o tipo da política: DBMS_REDACT.PARTIAL. Note que estamos mascarando os dados para todos os usuários que não fazem parte da role SUPERVISOR:

SQL> BEGIN
    DBMS_REDACT.ADD_POLICY(object_schema => 'TESTE',
     object_name => 'TB_FUNCIONARIOS',
     column_name => 'CPF',
     policy_name => 'redact_funcionarios_cpf',
     function_type => DBMS_REDACT.PARTIAL,
     function_parameters => 'VVVFVVVFVVVFVV,VVV-VVV-VVV-VV,*,4,11',
     expression => 'SYS_CONTEXT(''SYS_SESSION_ROLES''
       ,''SUPERVISOR'') = ''FALSE''',
     policy_description => 'Mascaramento parcial',
     column_description => 'CPF do funcionario');
END;
/  

PL/SQL procedure successfully completed.

Agora quando consultarmos os funcionários, a coluna de dados sensível: CPF é demonstrada com os dados mascarados:

SQL> select * from tb_funcionarios;

FUNCIONARIO                    CPF
------------------------------ ---------------
Maria                          123-***-***-**
Renan                          234-***-***-**
Lucas                          566-***-***-**

Vamos fazer outro teste, vamos liberar a visualização dos dados reais para um usuário. Para isso vamos criar o usuario(teste2) e vamos conceder permissões para ele consultar os dados da tabela de funcionários do esquema teste:

SQL> create user teste2 identified by teste2;
User created.

SQL> grant resource to teste2;
Grant succeeded.

SQL> grant connect to teste2;
Grant succeeded.

SQL> grant select on teste.tb_funcionarios to teste2;
Grant succeeded.

Vamos ver o resultado da consulta aos dados quando nos conectamos com o usuário teste2:

SQL> conn teste2/teste2
Connected.

SQL> select * from teste.tb_funcionarios;

FUNCIONARIO    CPF
-------------- ---------------
Maria          123-***-***-**
Renan          234-***-***-**
Lucas          566-***-***-**

Tudo certo, os dados aparecem mascarados para qualquer usuário que não faz parte da role SUPERVISOR. Os usuários que fazem parte desta role conseguirão ver os dados reais. Vamos testar.

Primeiro revogo o privilégio concedido para o usuário teste2:

SQL> revoke select on teste.tb_funcionarios from teste2; 
Revoke succeeded.

Depois criamos a role supervisor e concedemos o grant de seleção a tabela para role:

SQL> create role SUPERVISOR;
Role created.

SQL> grant select on teste.tb_funcionarios to SUPERVISOR;
Grant succeeded.

Concedemos a role SUPERVISOR ao usuário teste2

SQL> grant SUPERVISOR to teste2;
Grant succeeded.

Agora quando consultarmos os dados novamente com o usuário teste2, como ele já tem atribuído a role SUPERVISOR , ele conseguirá ver os dados reais, conforme vemos abaixo:

SQL> discon
Disconnected from Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options

SQL> conn teste2/teste2
Connected.

SQL> select * from teste.tb_funcionarios;

FUNCIONARIO    CPF
-------------- ---------------
Maria          123.234.345-09
Renan          234.122.899-08
Lucas          566.989.977-10

SQL>

3 - Exemplo: Política – Expressão Regular

Vamos fazer um exemplo utilizando a expressão regular. Criamos outra tabela para armazenar alguns contatos e inserimos alguns contatos:

SQL> create table tb_contato (NOME VARCHAR2(30),EMAIL VARCHAR2(50));
Table created.

SQL> insert into tb_contato values('Ana da Silva','anasilva@gmail.com');
1 row created.

insert into tb_contato values('Robert Willian','robertw@uol.com.br');
1 row created.

insert into tb_contato values('Maria Aparecida da Silva','mpsilva@bol.com');
1 row created.

SQL> commit;
Commit complete.

Realizamos nossa consulta na tabela de contatos e vemos os contatos com seus respectivos e-mails:

SQL> select * from tb_contato;

NOME                      EMAIL
------------------------- --------------------------------------------------
Ana da Silva              anasilva@gmail.com
Robert Willian            robertw@uol.com.br
Maria Aparecida da Silva  mpsilva@bol.com

Criamos a política utilizando expressão regular conforme abaixo:

BEGIN
    DBMS_REDACT.ADD_POLICY(
     object_schema => 'TESTE',
     object_name => 'TB_CONTATO',
     column_name => 'EMAIL',
     policy_name => 'redact_contato_email',
     function_type => DBMS_REDACT.REGEXP,
     function_parameters => NULL,
     expression => '1=1',
     regexp_pattern => DBMS_REDACT.RE_PATTERN_EMAIL_ADDRESS,
     regexp_replace_string => DBMS_REDACT.RE_REDACT_EMAIL_NAME,
     regexp_position => DBMS_REDACT.RE_BEGINNING,
     regexp_occurrence => DBMS_REDACT.RE_FIRST,
     regexp_match_parameter => DBMS_REDACT.RE_CASE_INSENSITIVE
);
END;
/

PL/SQL procedure successfully completed.

Agora quando é consultado os contatos novamente, vemos que a primeira parte dos e-mails foram mascarados:

SQL> select * from tb_contato;

NOME                     EMAIL
------------------------ -------------------------
Ana da Silva             xxxx@gmail.com
Robert Willian           xxxx@uol.com.br
Maria Aparecida da Silva xxxx@bol.com

4 - Exemplo: Política – Random Redaction

Vamos fazer um exemplo utilizando agora a política de mascaramento randômico. Esta política é fantástica, pois a cada vez que consultarmos os dados na tabela, o retorno é devolvido mascarado de uma maneira que a máscara é modificada a cada execução da consulta.

Primeiro criamos uma tabela de telefone que terá o nome e o telefone dos clientes. Inserimos alguns registros na sequência:

SQL> create table tb_fone (NOME VARCHAR2(30),TELEFONE VARCHAR2(20));
Table created.

SQL> insert into tb_fone values('João da Silva','8818-9909');
1 row created.

insert into tb_fone values('Marcos Willian','2123-3314');
1 row created.

insert into tb_fone values('José Aparecido da Silva','3245-8976');
1 row created.

SQL> commit;
Commit complete.

Consultamos nossos telefones na tabela:

SQL> select * from tb_fone;

NOME                   TELEFONE
---------------------- --------------------
Jo??o da Silva         8818-9909
Marcos Willian         2123-3314

Aplicamos agora a política randômica sobre a coluna telefone na nossa tabela conforme abaixo:

BEGIN
    DBMS_REDACT.ADD_POLICY(
     object_schema => 'TESTE',
     object_name => 'TB_FONE',
     column_name => 'TELEFONE',
     policy_name => 'redact_fone',
     function_type => DBMS_REDACT.RANDOM,
     expression => '1=1');
END;
/

PL/SQL procedure successfully completed.

E por fim, consultamos algumas vezes os telefones na tabela. Perceba que a coluna telefone foi mascarada e é modificada a cada execução da consulta:

SQL> select * from tb_fone;

NOME              TELEFONE
---------------- --------------------
Jo??o da Silva    7A\iG5?
Marcos Willian    oHo{X9w

SQL> select * from tb_fone;

NOME              TELEFONE
---------------- --------------------
Jo??o da Silva    gD?y@Y4
Marcos Willian    kH=QSoIs

Para ver as politicas habilitadas podemos fazer a consulta abaixo:

select OBJECT_OWNER,object_name, policy_name, enable from REDACTION_POLICIES;

Se quiser habilitar/desabilitar ou excluir a política, podemos utilizar os comandos abaixo:

Para desabilitar uma politica

SQL> BEGIN
    DBMS_REDACT.DISABLE_POLICY (
     object_schema => 'TESTE',
     object_name => 'TB_FUNCIONARIOS',
     policy_name => 'redact_funcionarios_cpf');
END;
/ 

PL/SQL procedure successfully completed.

SQL> select * from tb_funcionarios;

FUNCIONARIO                    CPF
------------------------------ ---------------
Maria                          123.234.345-09
Renan                          234.122.899-08
Lucas                          566.989.977-10
SQL>

Para Habilitar uma política

BEGIN
   DBMS_REDACT.ENABLE_POLICY (
    object_schema => 'TESTE',
    object_name => 'TB_FUNCIONARIOS',
    policy_name => 'redact_funcionarios_cpf');
END;
/

PL/SQL procedure successfully completed.

SQL> select * from tb_funcionarios;

FUNCIONARIO                    CPF
------------------------------ ---------------
Maria                          123-***-***-**
Renan                          234-***-***-**
Lucas                          566-***-***-**

Para Remover uma política

BEGIN
    DBMS_REDACT.DROP_POLICY (
     object_schema => ‘TESTE’,
     object_name => ‘TB_FUNCIONARIOS’,
     policy_name => ‘redact_funcionarios_cpf’);
END;
/

Pessoal, os exemplos acima são apenas uma gota no oceano do que pode ser feito utilizando esta feature.

Para maiores informações, segue link da documentação da Oracle:


https://docs.oracle.com/cd/E11882_01/network.112/e40393/redaction_config.htm#ASOAG10490

http://docs.oracle.com/database/121/ARPLS/d_redact.htm#ARPLS73800

Abraço,

Ronaldo.

Nenhum comentário:

Postar um comentário