Pular para o conteúdo principal

Usando bind variables para solucionar problemas de segurança no Oracle



- Sabemos que existe vários casos onde o uso de bind variables pode nos ajudar bastante do ponto de vista da peformance das consultas, mas uma outra área que devemos ter cuidado ao usar binds, é a da segurança de nosso banco. Vou mostrar na prática como o uso de bind pode nos ajudar a dar mais segurança ao código.


- Faço a criação da nossa tabela de testes e depois faço insert de algumas linhas.

create table clientes (pri_nome varchar2(50), ult_nome varchar2(50));

insert into clientes values ('Thiago','Castro');
insert into clientes values ('Lucas','Costa');
insert into clientes values ('João','Souza');
insert into clientes values ('Antônio','Pereira');
commit;

1 row created.
SQL>
1 row created.
SQL>
1 row created.
SQL>
1 row created.
SQL>
Commit complete.




- Vamos criar uma procedure bem simples, a teste_inject. Como podemos ver no código, ela pega o parâmetro passado, o ultimo nome do cliente, e faz uma contagem na tabela de clientes para saber a quantidade de clientes que tenho com o sobre nome passado.


CREATE OR REPLACE PROCEDURE teste_inject_s_bind (nome in clientes.ult_nome%TYPE) IS
BEGIN
   DECLARE
       texto VARCHAR2(2000);
       contagem NUMBER;
       BEGIN
       texto := 'SELECT COUNT(*) FROM clientes s WHERE s.ult_nome= '''||nome||'''';
       EXECUTE IMMEDIATE texto INTO contagem;
       DBMS_OUTPUT.PUT_LINE ('Quantidade de clientes: '||TO_CHAR(contagem));
       END;
END teste_inject_s_bind;
/

Procedure created.



-  Executei a procedure de duas formas. Na primeira forma, com o comportamento normal do programa e na segunda passei um parâmetro diferente que  alterou o comportamento do código. Sei que nesse exemplo isso não quer dizer muita coisa, mas imaginem se nessa tabela estivessem dados sigilosos.

Abaixo o comportamento da procedure com os dois parâmetros:


Execução 1
SQL> exec teste_inject_s_bind('Castro');
Quantidade de clientes: 1

PL/SQL procedure successfully completed.


Execução 2
SQL> exec teste_inject_s_bind(''' or 1=1--');
Quantidade de clientes: 4

PL/SQL procedure successfully completed.



SQL> SELECT COUNT(*) FROM clientes s WHERE s.ult_nome='' or 1=1--';

  COUNT(*)
----------
     4


   
- Certo sabemos que o código tem uma falha, o que fazer para consertar o problema? Na procedure teste_inject_s_bind se tivéssemos usado binds, evitaríamos esse problema. Então vamos criar uma nova procedure, só que agora com uso de bind.



CREATE OR REPLACE procedure teste_inject_c_bind (nome in clientes.ult_nome%TYPE) IS
BEGIN
   DECLARE 
       texto VARCHAR2(2000);
       contagem NUMBER;
       BEGIN
       texto := 'SELECT COUNT(*) FROM clientes s WHERE s.ult_nome= :p_nome';
       EXECUTE IMMEDIATE texto INTO contagem USING nome;
       DBMS_OUTPUT.PUT_LINE ('Quantidade de clientes: '||TO_CHAR(contagem));
       END;
END teste_inject_c_bind;
/

Procedure created.
   


- Agora vamos executar a nova procedure com os mesmos parâmetros.


1 Execução
SQL> exec teste_inject_c_bind('Castro');
Quantidade de clientes: 1

PL/SQL procedure successfully completed.



2 Execução
SQL> exec teste_inject_c_bind(''' or 1=1--');
Quantidade de clientes: 0

PL/SQL procedure successfully completed.




- Repare que na segunda execução da teste_inject_c_bind, o retorno foi 0, ou seja, o nosso parâmetro para alterar o resultado da consulta não funcionou.

Comentários

Postagens mais visitadas deste blog

Configurando a política de retenção de backups no RMAN

                       Configurando a politica de reten çã o de backups no RMAN        O objetivo deste post é explicar como podemos configurar a reten çã o de backups na poderosa ferramenta de backup do bando de dados Oracle RMAN. Podemos configurar nossa pol í tica tendo por base dois tipos: janela de recupera çã o (recovery window) ou redundãncia (redundancy). Abaixo iremos abordar os dois tipos.       Para identificar qual dos dois tipos o RMAN está usando, use: RMAN> show retention policy; Política baseada em redundância CONFIGURE RETENTION POLICY TO REDUNDANCY 1; Política baseada em janela de recuperação CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 2 DAYS; ·        Política baseada em redund â ncia ( REDUNDANCY )       De uma maneira bem simples e objetiva, o par â met...

ORA-01623 ORA-00312 - Removendo redo logs

Após realizar um restore de um ambiente de Oracle RAC para um single instance usando snapshot de storage, tentei recriar os redo logs recebi o seguinte erro durante a exclusão de um grupo de discos. SQL> alter database drop logfile group 2; ORA-01623: o log 2 é o log atual para a instância UOW (thread 1) - não é possível eliminar ORA-00312: thread 2 do log 1 on-line: '+DATA/UOW/ONLINELOG/group_2.1638.1051804433' ORA-00312: thread 2 do log 1 on-line: '+DATA/UOW/ONLINELOG/group_2.981.1051804433' O erro quer dizer que o grupo de redo pertence a outra thread. Quer dizer que ele pertence a outra instância do ambiente RAC. Como no meu caso não precisarei mais dela, basta usar o comando: SAL> alter database disable thread 2; Database altered.   Usei o SQL abaixo para gerar os comandos para excluir os redo logs SQL> select distinct 'alter database drop logfile group '||(group#)||';' from v$log where thread#=2; 'ALTERDATABASEDROPLOGFILEGROUP'||(G...

Oracleasm Deletedisk - Unable to open device or resource busy failed Unable to clear disk

Após a migração de storages utilizando Oracle ASM em um ambiente, precisei remover os discos que não estavam mais sendo utilizados. Porém quando fui utilizar o deletedisk no oracleasm recebi o seguinte erro: # oracleasm deletedisk -v HITACHI33 Clearing disk header: oracleasm-write-label: Unable to open device "/dev/oracleasm/disks/HITACHI33": Device or resource busy failed Unable to clear disk "HITACHI33" Fiz a verificação para ver ser o disco ainda estava em uso, mas não obtive nenhum retorno: # fuser /dev/oracleasm/disks/HITACHI33 # lsof /dev/oracleasm/disks/HITACHI33 Então lendo alguns posts e artigos vi que o problema poderia estar relacionado ao multipath do sistema operacional. Então utilizei o -f para realizar um flush, mas recebi a mensagem abaixo: # multipath -f /dev/oracleasm/disks/HITACHI33 Jun 22 08:43:21 | must provide a map name to remove Utilizei o comando do ASM para verificar o mapeamento do disco....