Mascarando Valores

Mascarando valores de colunas

Sua base tem dados sigilosos, informações de cartão de crédito, emails ou alguma outra informação que você não quer que as pessoas visualizem normalmente?
Bem, se você tem esta “bomba” para resolver em tua base, fique tranquilo!
No Oracle12c foi adicionado uma funcionalidade chamada REDACT, que permite que ocultemos o valor ( ou parte dele ) das colunas desejadas. Além disto ele permite que restrinjamos o acesso à apenas alguns usuários.

Vamos para um cenário bem simples:

Imagine que temos uma tabela que possui as seguintes informações:

 

CREATE table BONS_PAGADORES(
	id NUMBER,
	cartao VARCHAR2(128),
	verificador VARCHAR2(16),
	cpf VARCHAR2(32),
	email VARCHAR2(256),
	nome VARCHAR2(512)
);
insert into BONS_PAGADORES values ( 1 , '8888-9999-0000-4444',
	'123','123456789-01','eu@dartanghan.com','Dartanghan 1');
insert into BONS_PAGADORES values ( 2 , '7777-8888-0000-4444',
	'123','123456789-02','eu@dartanghan.com','Dartanghan 2');
insert into BONS_PAGADORES values ( 3 , '6666-7777-0000-4444',
	'123','123456789-03','eu@dartanghan.com','Dartanghan 3');
insert into BONS_PAGADORES values ( 4 , '4444-5555-0000-4444',
	'123','123456789-04','eu@dartanghan.com','Dartanghan 4');

ID CARTAO VERIFICADOR CPF EMAIL NOME
1 8888-9999-0000-4444 123 123456789-01 eu@dartanghan.com Dartanghan 1
2 7777-8888-0000-4444 123 123456789-02 eu@dartanghan.com Dartanghan 2
3 6666-7777-0000-4444 123 123456789-03 eu@dartanghan.com Dartanghan 3
4 4444-5555-0000-4444 123 123456789-04 eu@dartanghan.com Dartanghan 4

Agora vamos imaginar que nossa aplicação ( representada pelo usuário APP_USER ) não deva ler os números de cartão de crédito, nem os verificadores.
Como ainda não aplicamos nenhuma regra, teríamos :

SQL> col cartao format a20;
SQL> select cartao,verificador from app_master.bons_pagadores;

CARTAO		     VERIFICADOR
-------------------- ----------------
8888-9999-0000-4444  123
7777-8888-0000-4444  123
6666-7777-0000-4444  123
4444-5555-0000-4444  123

Como restringir acesso à determinadas colunas?

Bem, como mencionei acima, o oracle 12c nos traz a funcionalidade de REDACT. Nessa funcionalidade podemos criar uma POLICY que será aplicada para um determinado objeto e, dentro desta policy, poderemos adicionar N colunas restritas.

Para criar uma policy é muito simples:

begin
dbms_redact.add_policy( 
	object_schema=>'APP_MASTER',  
	object_name=>'BONS_PAGADORES', 
	policy_name=>'RESTRICAO_DOS_BONS', 
	expression=>'USER=''APP_USER''');
end;
/

No exemplo acima, definimos uma POLICY chamada RESTRICAO_DOS_BONS, onde está amarrada ao objeto APP_MASTER.BONS_PAGADORES.
Esta policy será aplicada apenas quando o usuário APP_USER tentar acessar os dados.

Porém ainda não definimos o que pode ou não ser visto. Para isso adicionaremos as colunas restritas à esta nova policy criada com:

begin
dbms_redact.alter_policy(
	object_schema=>'APP_MASTER',  
	object_name=>'BONS_PAGADORES', 
	policy_name=>'RESTRICAO_DOS_BONS', 
	action=>dbms_redact.add_column,
	column_name=>'VERIFICADOR',
	function_type=> dbms_redact.random	
);
dbms_redact.alter_policy(
	object_schema=>'APP_MASTER',  
	object_name=>'BONS_PAGADORES', 
	policy_name=>'RESTRICAO_DOS_BONS', 
	action=>dbms_redact.add_column,
	column_name=>'CARTAO',
	function_type=> dbms_redact.partial,
	function_parameters=>'VVVVFVVVVFVVVVFVVVV,VVVV-VVVV-VVVV-VVVV,*,1,8'	
);

end;
/

Este código estamos informando que a policy RESTRICAO_DOS_BONS deverá alterar todos os caracteres da coluna VERIFICADOR para valores aleatórios e que pegará os oito primeiros dígitos do cartão e transformará em ‘*’

Olha que coisa linda que fica nossa query ao usarmos o usuário APP_USER 🙂

CARTAO VERIFICADOR
****-****-0000-4444  
****-****-0000-4444 x(\
****-****-0000-4444 D.%
****-****-0000-4444 d-j

Explicando…

Para aplicarmos caracteres aleatórios à um campo, utilizamos function_type=> dbms_redact.random. Ela dispensa parâmetros extras e já é suficiente para esconder um conteúdo. Caso queira deixar a visualização mais “aceitável”, podemos usar o PARTIAL.
Usando a opção function_type=> dbms_redact.partial, informamos que apenas parte de nosso campo será mascarado.
Para informar tal, usamos o parâmetro function_parameters que recebe uma string dividida em quatro sessões:

1) Formato que será trabalhado: No primeiro bloco da string ( definido por VVVVFVVVVFVVVVFVVVV ), dizemos quais posições serão analisadas pelo controle de re-escrita e quais ficaram estáticas. Os valores em V identificam onde será aplicada a nova máscara e os valores em F mostram quais valores serão estáticos.

2) Define o formato que será visualizado: O segundo bloco ( VVVV-VVVV-VVVV-VVVV ) diz qual será o formato de exibição do campo. Observe que trocamos os ‘F’ por ‘-‘ e mantivemos os ‘V’.

3) Caractere que será utilizado para mascarar a informação definida como V

4) Caractere de início da mascara ( aqui pegamos desde o primeiro caractere );

5) Número de caracteres mascarados. Apenas colocaremos o ‘*’ em oito caracteres, demais caracteres serão exibidos.

Para maiores informações, por favor, consulte:
http://docs.oracle.com/cd/E16655_01/network.121/e17729/redaction_config.htm#ASOAG10556

Removendo uma POLICY

Bem, em algum momento de sua vida, se você criou uma policy para redact, será necessário deletá-la.
Para isso, basta usar o método DROP_POLICY, como no exemplo:

begin
dbms_redact.drop_policy( 
	object_schema=>'APP_MASTER',  
	object_name=>'BONS_PAGADORES', 
	policy_name=>'RESTRICAO_DOS_BONS' 
);
end;
/

Conclusão

Apesar de ser trabalhoso, o REDACT é uma baita funcionalidade disponível. Ela poupa muitas horas de desenvolvimento ou de gambiarras na parte do software para mascarar dados e o melhor, traz maior segurança até mesmo para a aplicação e ao servidor.

Mas lembre-se, o REDACT NÃO ALTERA O VALOR DA COLUNA MASCARADA! Ele apenas exibe o valor diferente para omitir informações sensíveis e, por consequência, podemos continuar fazendo UPDATES, INSERTs e DELETEs com o usuário “limitado”…


SQL> show user
USER is "APP_USER"
SQL> col cartao format a20;
SQL> select cartao,verificador,id from app_master.BONS_PAGADORES;

CARTAO		     VERIFICADOR	      ID
-------------------- ---------------- ----------
****-****-0000-4444  CT6		       1
****-****-0000-4444  ogR		       2
****-****-0000-4444  e\B		       3
****-****-0000-4444  tP`		       4

SQL> update app_master.BONS_PAGADORES set cartao='1234-1234-1234-1234' where id=1;

1 row updated.

SQL> commit;

Commit complete.

SQL> select cartao,verificador,id from app_master.BONS_PAGADORES;

CARTAO		     VERIFICADOR	      ID
-------------------- ---------------- ----------
****-****-1234-1234  b6l		       1
****-****-0000-4444  HQ 		       2
****-****-0000-4444  Wn@		       3
****-****-0000-4444  K^B		       4

No exemplo acima alteramos o valor do campo CARTAO normalmente, mesmo com o usuário APP_USER não podendo ver o valor do campo.

.

Deixe uma resposta