SQL Injection

No post você irá ter uma breve introdução sobre o assunto SQL Injection, além de exemplos de como isto pode acontecer e ver maneiras de como reduzir estes tipos de ataques.

SQL Injection é que um método de alterar o código SQL e assim ter acesso a dados não autorizados. Maioria das vezes isso ocorre ao tentar gerar SQL dinamicamente de maneira errada, como apenas concatenar strings, utilizando entradas do usuário, para formar o statement. Essas entradas são então “injetadas” no código SQL, modificando o comportamento da instrução executada. Esses ataques deverão ser considerados perigosos pois não é necessário autenticação no banco ou na aplicação e são relativamente fáceis de serem aplicados.

Vejamos agora um exemplo de como fazer um SQL Injection, utilizando uma procedure que deveria retornar os salários de todos os empregados de apenas um único departamento. Esse é um exemplo simples, mas com o SQL injection podemos até mesmo dropar tabelas, demonstrando o grande perigo de escrever código suscetível a ataques.

sqlplus terciocosta

SQL*Plus: Release 12.2.0.1.0 Production on Mon Mar 4 21:20:51 2019

Copyright (c) 1982, 2016, Oracle.  All rights reserved.

Enter password:
Last Successful login time: Mon Mar 04 2019 21:20:43 -03:00

Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

SQL> CREATE OR REPLACE PROCEDURE terciocosta.pr_get_sal(p_job_id VARCHAR2)
  2  IS
  3    v_stmt VARCHAR2(500);
  4    v_nome VARCHAR2(80);
  5    v_sal  NUMBER;
  6    v_cur  SYS_REFCURSOR;
  7  BEGIN
  8    v_stmt := 'SELECT em.first_name,
  9               em.salary
 10               FROM   hr.employees em
 11               WHERE  em.job_id = '''||p_job_id||'''';
 12    OPEN v_cur FOR v_stmt;
 13    LOOP
 14      FETCH v_cur INTO v_nome,v_sal;
 15      EXIT WHEN v_cur%NOTFOUND;
 16      DBMS_OUTPUT.PUT_LINE(v_nome||', salario '||v_sal);
 17    END LOOP;
 18  END;
 19  /

Procedure created.

SQL> SET SERVEROUTPUT ON SIZE UNLIMITED;
BEGIN terciocosta.pr_get_sal('IT_PROG'); END;
  2  /
Alexander, salario 9000
Bruce, salario 6000
David, salario 4800
Valli, salario 4800
Diana, salario 4200

PL/SQL procedure successfully completed.

Vamos rever o código acima. Foi utilizando uma instrução SQL concatenando o valor informando pelo usuário, que pode ser uma tela HTML por exemplo. Utilizamos a procedure e ela funcionou como esperada, retornando os salários apenas dos funcionários que pertencem ao departamento de IT_PROG.

Vejamos agora, como alguém, poderia maliciosamente, injetar um código SQL e modificar o comportamento da procedure.

BEGIN terciocosta.pr_get_sal('IT_PROG'' OR ''1''=''1'); END;
  2  /
Steven, salario 24000
Neena, salario 17000
Lex, salario 17000
Alexander, salario 9000
Bruce, salario 6000
David, salario 4800
Valli, salario 4800
Diana, salario 4200
Nancy, salario 12008
Daniel, salario 9000
John, salario 8200
Ismael, salario 7700
Jose Manuel, salario 7800
Luis, salario 6900
Den, salario 11000
Alexander, salario 3100
Shelli, salario 2900
Sigal, salario 2800
Guy, salario 2600
Karen, salario 2500
Matthew, salario 8000
Adam, salario 8200
Payam, salario 7900
Shanta, salario 6500
Kevin, salario 5800
Julia, salario 3200
Irene, salario 2700
James, salario 2400
Steven, salario 2200
Laura, salario 3300
Mozhe, salario 2800
James, salario 2500
TJ, salario 2100
Jason, salario 3300
Michael, salario 2900
Ki, salario 2400
Hazel, salario 2200
Renske, salario 3600
Stephen, salario 3200
John, salario 2700
Joshua, salario 2500
Trenna, salario 3500
Curtis, salario 3100
Randall, salario 2600
Peter, salario 2500
John, salario 14000
Karen, salario 13500
Alberto, salario 12000
Gerald, salario 11000
Eleni, salario 10500
Peter, salario 10000
David, salario 9500
Peter, salario 9000
Christopher, salario 8000
Nanette, salario 7500
Oliver, salario 7000
Janette, salario 10000
Patrick, salario 9500
Allan, salario 9000
Lindsey, salario 8000
Louise, salario 7500
Sarath, salario 7000
Clara, salario 10500
Danielle, salario 9500
Mattea, salario 7200
David, salario 6800
Sundar, salario 6400
Amit, salario 6200
Lisa, salario 11500
Harrison, salario 10000
Tayler, salario 9600
William, salario 7400
Elizabeth, salario 7300
Sundita, salario 6100
Ellen, salario 11000
Alyssa, salario 8800
Jonathon, salario 8600
Jack, salario 8400
Kimberely, salario 7000
Charles, salario 6200
Winston, salario 3200
Jean, salario 3100
Martha, salario 2500
Girard, salario 2800
Nandita, salario 4200
Alexis, salario 4100
Julia, salario 3400
Anthony, salario 3000
Kelly, salario 3800
Jennifer, salario 3600
Timothy, salario 2900
Randall, salario 2500
Sarah, salario 4000
Britney, salario 3900
Samuel, salario 3200
Vance, salario 2800
Alana, salario 3100
Kevin, salario 3000
Donald, salario 2600
Douglas, salario 2600
Jennifer, salario 4400
Michael, salario 13000
Pat, salario 6000
Susan, salario 6500
Hermann, salario 10000
Shelley, salario 12008
William, salario 8300

PL/SQL procedure successfully completed.

Perceba bem o que aconteceu. A entrada do usuário foi a string ‘IT_PROG” OR ”1”=”1’, e assim modificando a instrução SQL para:

SELECT em.first_name,
       em.salary
FROM   hr.employees em
WHERE  em.job_id = 'IT_PROG' OR '1'='1'

Modificando a condição do nosso WHERE, OR ‘1’ = ‘1’, para sempre verdadeiro, retornando sempre todas as linhas da tabela. Isso demonstra o que um código mal formado pode criar riscos para a nossa aplicação.

Existe alguns tipos de SQL Injection, veja quais são os principais:

  • First Order Attack – Alterando a string que será concatenada na query, alterando assim o seu objectivo e tendo acesso a informações não autorizadas. Esse foi o exemplo acima, onde foi feito um curto circuito no WHERE para sempre ser positivo. Outras alternativas seria utilizar um UNION, ou até mesmo uma subquery.
  • Second Order Attack – Isso ocorre quando o usuário injeta permanentemente no banco, via uma linha na tabela(INSERT), e após isso tenta se aproveitar de alguma função do sistema. Um exemplo seria como cadastrar um usuário. O usuário poderiar criar um usuário com o nome X’ OR username = ‘JANE. Assim, esse usuário poderá ser utilizado em uma query para pegar alguma informação confidencial do usuário logado, Mas se for via concatenação, a informação retornada será o usuário JANE.
  • Lateral Injection Attack – Esse ataque acontece quando se alterar os valores das variáveis de ambiente NLS_Date_Format  e NLS_Numeric_Characters e assim modificar o comportamento padrão de funções como TO_DATE.

Como então evitar código que seja suscetíveis a SQL Injection? Bem, existe mais de uma maneira de fazer isto. Uma maneira de fazer isto é por evitar o uso de SQL dinâmicos, se neste caso poder ser utilizado um SQL estático. Mas, casi seja necessário utilizar o SQL dinâmico, que se utilize com variáveis do tipo bind e não concatenando a string. Aqui no blog já existe informação sobre SQL Dinâmico e bind variables.

Outra forma de reduzir as chances de alguém se aproveitar do código é por minimar os privilégios do usuário sendo utilizado na aplicação, reduzindo assim a área de ataque, ou attack surface. Além de minimizar os privilégios de usuário em questão, uma outra técnica é de utilizar programas com a opção INVOKER´S RIGHT. Assim o atacante não tenta se aproveitar de uma procedure de um usuário que tem mais privilégios.

Mas, caso queria e seja necessário concatenar strings(duvido muito)? Podemos filtrar e verificar o input do usuário antes de utilizar. Isso previne que se aproveitem da concatenação de strings. Isso é realizado com a package DMBS_ASSERT. Essa package já foi discutido aqui, conforme pode ser vista no seguinte link: https://oraclepress.wordpress.com/2018/05/30/use-dbms_assert/

Anúncios

Meu nome é Tércio Costa, sou formado em Ciências da Computação pela UFPB, tenho a certificação Oracle SQL Expert e OCP PL/SQL, mantendo um blog reconhecido pela OTN(oraclepress.wordpress.com), no qual também publico artigos técnicos no portal OTN, no portal http://www.profissionaloracle.com.br/gpo e na revista SQL Magazine. Além de tudo isto sou um Oracle ACE Associate por estar sempre contribuindo para a comunidade com um bom nível de expertise.

Marcado com: , ,
Publicado em Sem categoria

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google

Você está comentando utilizando sua conta Google. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.

Esse Blog é reconhecido pela
Certificações
Sou articulista

Clique para seguir este blog e receber notificações via email de novos posts.

Tércio Costa

Tércio Costa

Meu nome é Tércio Costa, sou formado em Ciências da Computação pela UFPB, tenho a certificação Oracle SQL Expert e OCP PL/SQL, mantendo um blog reconhecido pela OTN(oraclepress.wordpress.com), no qual também publico artigos técnicos no portal OTN, no portal http://www.profissionaloracle.com.br/gpo e na revista SQL Magazine. Além de tudo isto sou um Oracle ACE Associate por estar sempre contribuindo para a comunidade com um bom nível de expertise.

Links Pessoais

Serviços verificados

Visualizar Perfil Completo →

Total de Visualizações da Página
  • 138.077 Visualizações
%d blogueiros gostam disto: