Unconfigured Ad Widget

Collapse

Anúncio

Collapse
No announcement yet.

Proteção contra Sql Injection !

Collapse
X
 
  • Filter
  • Tempo
  • Show
Clear All
new posts

  • Font Size
    #1

    Proteção contra Sql Injection !

    O que é SQL Injection?



    O SQL Injection ou injeção no SQL é uma vulnerabilidade que ocorre em aplicações web. O principal motivo de ela acontecer é que o programador não faz o tratamento necessário das variáveis que serão passadas pelos métodos GET ou POST (ao decorrer do artigo veremos como funciona esse métodos), com isso nos permite injetar diretamente ou pela URL ou Formulários comandos SQL para consulta, modificação ou exclusão de tabelas, colunas e valores.


    A linguagem (SQL Structured Query Language) é uma linguagem nativa que será utilizada em todos os serviços como MySQL, MSSQL, Postgre, Oracle, entre outras. O seu principal objetivo é nos permitir trabalhar e manipular diferentes tipos de dados organizados em Matrizes, onde temos na horizontal colunas e na vertical linhas.


    Cada campo é chamado de tuplas, as tuplas são onde os dados ficarão armazenados de acordo com o seu tipo e o tipo da coluna que foi definida. Ou seja não é possível armazenar em um campo de uma tabela que foi definido como inteiro e armazenar char.


    Nos BDs atuais eles trabalham com MER (Modelo entidade relacionamento), para entendermos a injeção de SQL vou dar uma pequena revisava de como funciona os SGBD (vou usar como exemplo MySQL).

    Vamos imaginar que temos uma empresa e essa empresa se divide em setores, cada setor vamos chamar de Área Funcional. Nesse exemplo temos 3 setores, Produtos, Venda, Financeiro.


    Vou efetuar algumas analogias nesse exemplo para ficar mais fácil a compreensão. Vamos pensar da seguinte maneira o setor produtos tem as seguintes características (código, produto, preço), a venda tem (código da venda, código do vendedor, código produto, total), e Financeiro (caixa, entrada, saída, saldo). Não vou falar das relações pois se for tratar de entidade relacionamento ao pé da letra vai ficar muito grande o artigo, para aqueles que se interessam recomendo o livro Projeto e Modelagem de Bancos de Dados.


    Então ficou assim

    Produtos – > código, produto, preço

    Venda – > código da venda, código do vendedor, código do produto, total

    Financeiro – > caixa, entrada, saída, saldo

    Vamos agora imaginar isso em um banco de dados, cada Área funcional será uma tabela, e cada característica será um campo da tabela. Vou pegar como exemplo a tabela produtos.


    Cada dupla pode receber um valor como por exemplo, código -> inteiro, produto – > String, preço -> Real

    Por exemplo é cadastrado 2 produtos.


    Bem acabamos de ver um exemplo prático de como o SGBD armazena os dados em tabelas. Isso se aplica nas outras tabelas que será utilizado no sistema. Não vou estender mais sobre o funcionamento, quem quiser estudar mais sobre fique a vontade como chaves primárias, chaves estrangeiras, relações AxB …


    Bem a partir daqui já temos uma noção de como o SGBD funciona, podemos partir para a prática. Quando um código é escrito para fazer uma consulta e retornar um determinado valor é necessário levar algumas considerações quanto a segurança que será passada.


    Vamos analisar códigos (não vou entrar em detalhes da linguagem mas irei comentar cada linha)


    Os métodos para captura e parâmetros passados:

    Passagem pelo método GET

    Pag1.php

    <?php

    $nome=$_GET[‘nome’];

    ?>

    O método GET pega os parâmetros passados via URL, para simplificar vai um exemplo:


    Pag1.php?nome=Parâmetro


    Ahhh ficou mais claro né, então o nosso código vai pegar o que será passado depois do = e irá armazenar dentro da variável nome. Esse método é muito utilizado em páginas que o conteúdo de uma determinada página é listada através do “id” identificador que está como chave primária no banco de dados, mais a frente iremos ver detalhadamente isso.

    Passagem pelo método POST


    O método POST diferentemente do GET os seus parâmetros não são passados via URL e sim diretamente pelo formulário, ele é muito utilizado quando em um sistema de cadastro em php precisamos passar valores como nome, email, rg, cpf, entre outros, como são dados grandes então não é viável utilizar o método GET para isso. A forma de se usar o método post é exatamente da mesma forma.

    Pag1.php

    <?php

    $nome=$_POST['nome'];

    ?>

    No caso precisaremos de um formulário

    <form name="dados" method="post" action="Pag1.php">

    <input type="text" name="nome">

    </form>

    Reparem que o nome do componente do tipo text tem que ser exatamente o nome que será passado para ser capturado.


    Bem nós acabamos de entender o funcionamento de ambos.


    Injeção o SQL Via método GET


    Vamos analisar um exemplo de uma página em php vulnerável a injeção de SQL

    <?php //inicio do php

    //Fazer conexão com o banco

    $conexao = mysql_connect("endereço do banco", "login", "senha")

    or die ("Erro na conexão ao banco de dados.");//Se a conexão não for bem sucedida exibe a mensagem

    $db = mysql_select_db("site")//Seleciono a base de dados no caso (site)

    or die ("Erro ao selecionar a base de dados.");//Se a base não existir exibe a mensagem

    $id=$_GET['id'];//Passagem de parâmetros pelo método post

    /*

    A variável resultado recebe a função mysql_query cuja a sua função é executar uma determinada linha em SQL. Vou dar um Select na tabela noticias onde irei exibir a linha que o id for = a variável id, ou seja a variável passada pelo método GET, e seleciono a variável conexão para ela ser feita.

    /*

    $resultado = mysql_query("SELECT * FROM noticias WHERE id=$id", $conexao);

    /*

    Entro em um loop onde a variável linha recebe a função mysql_fetch_array, a finalidade dessa função é colocar cada linha da tabela em forma de um vetor.

    /*

    while($linha = mysql_fetch_array($resultado, MYSQL_ASSOC)){

    echo $linha['texto'];//Exibe a variável linha onde o campo da coluna tem o nome de texto

    echo "<br/>";//Pula linha

    }

    ?>//fim do php

    Esse exemplo clássico é extremamente vulnerável e tenha certeza todos os web designers utilizam disso para exibir o conteúdo na tela.


    Para entendermos melhor vou mostrar para você como a tabela noticias está modelada


    Id -> chave primária (int(11))

    nome -> (varchar (40))

    titulo -> (varchar(200))

    resumo -> (varchar(250))

    texto -> text

    ver -> tinyint(1)


    Bem o id é referente ao id referente a cada dado que é inserido e armazena no total de 11 caracteres do tipo inteiro, nome é o nome do Autor do tipo varchar e armazena total de 40 caracteres, titulo armazena o título da notícia de 200 caracteres do tipo varchar, resumo é o resumo da notícia que armazena total de 250 caracteres do tipo varchar, texto é onde será armazenado o texto da notícia em si do tipo text, ver é a variável de referência que indica se esses dados serão ou não exibidos do tipo tinyint se ela for 1 ela exibe, se for 0 os dados não são exibidos.


    Agora Marcelo o que ocorreria se ao passar o id e adicionarmos uma ‘ no fim dele ? Supondo que o id passado será o número 1.

    Exemplo: Pag1.php?id=1′

    $resultado = mysql_query("SELECT * FROM noticias WHERE id=1'", $conexao);

    Aconteceu que fechamos prematuramente a query isso vai retornar um erro.


    Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in C:\xampp\htdocs\vul.php on line 18

    O erro ocorreu exatamente na linha 18 quando o loop é executado, ocorre que não filtramos a passagem dos parâmetros e nos retornou erro dizendo que foi acusado.


    Humm… isso quer dizer que não temos filtragem do que passa pelo método GET, então podemos inserir códigos SQL na URL exemplo:


    Pag1.php?id=-1+union+select+1,2,3,4,5,6,7 -> Com erro

    Pag1.php?id=-1+union+select+1,2,3,4,5,6 -> Sem erro


    O comando union em sql serve para unir de forma ascendente os campos da tabela atual. Mas pera ai, o que quer dizer esses números ??


    Esses números indicam a quantidade de colunas da tabela. Mas qual Tabela ?? a tabela atual no caso notícias, para simplificar e entender melhor seria isso que estamos fazendo:


    Pag1.php?id=-1+union+select+ id,nome,titulo,resumo,texto,ver


    Ele nos irá retornar erro na coluna 5 pois a 5 que estamos exibindo para o usuário, a partir dai é só comandos SQL simples.


    Agora Marcelo mas como podemos corrigir isso ?


    Existe uma forma mas muito simples de corrigir isso =) Usando casting, a função do casting é indicar que o que está sendo passado é de um determinado tipo (Vale lembrar podemos usar o casting apenas quando estamos recebendo números como parâmetros). Vejamos

    $id=(int)$_GET['id'];

    Ali indicamos que os parâmetros que estão sendo passados é do tipo inteiro, então tudo que passar diferente de inteiro exemplo char será convertido para int.


    Outra forma podemos apenas substituir determinados comandos por outros vejamos.

    $id=strtr($id, '\'', '*');

    Mas Marcelo e o método POST ?? A passagem pelo método post é feito através de formulários, então precisaremos de um, vamos usar o acima de exemplo.

    <form name="dados" method="post" action="Pag1.php">

    <input type="text" name="nome">

    </form>

    PHP:

    $nome=$_POST['nome'];

    $nome=strtr($nome, '\'', '*');

    O tratamento é feito exatamente da mesma forma, mas nesse caso não podemos utilizar do casting pois nem todos os dados passados são inteiros, exemplo um formulário de login e senha é passado tipos varchar, então podemos usar a função strtr para trocar determinados caracteres por outros.


    Para aqueles que querem algo mais específicos basta fazer uma função para a verificação, ou para preguiçosos procurar no google que com certeza irá encontrar várias funções para tratamento de SQL Injection.


    Quem tiver dúvidas perguntem.

    FONTE: Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar...

    Intel core i7 2ªgeração, 8gb Ram, Intel HD 3000, HDD 500gb
    --------------------------------------------------------------------------------------
X
Working...
X