Evitando Injeção SQL (parte 2)

NomeSenha

 

<form
nam
e="frmLogin" action="login.asp" method="post">Nome : <input type=”text” name=”nomeUsuario”>Senha: <input type=”text” name=”senhaUsuario”>

<input type=”Enviar”>

</form>

Geralmente quando o usuário clicar no botão – Enviar – o script login.asp será executado para efetuar a validação dos dados informados. Abaixo temos um script típico para um arquivo de validação de informações:

<%
dim nomeUsuario, senhaUsuario, consulta
dim conn, rS

nomeUsuario = Request.Form(“nomeUsuario”)
senhaUsuario = Request.Form(“senhaUsuario”)

set conn = server.createObject(“ADODB.Connection”)
set rs = server.createObject(“ADODB.Recordset”)

consulta = “select count(*) from usuarios where nomeUsuario='” & nomeUsuario & “‘ and senhaUsuario='” & senhaUsuario & “‘”

conn.Open “Provider=SQLOLEDB; Data Source=(local);
Initial Catalog=myDB; User Id=sa; senhaUsuario=”

rs.activeConnection = conn
rs.open consulta

if not rs.eof then
response.write “Acesso Concedido”
else
response.write “Acesso Negado”
end if
%>

Vamos analisar o que ocorre quando um usuário tenta se autenticar. Vamos supor que ele é usuário cadastrado com nome Macoratti e senha 123456 (só suposição). Ao informar o nome e a senha e clicar no botão Enviar o script do arquivo login.asp será executado. Vamos ver como ficou a instrução SQL montada neste caso :

select count(*) from usuarios where nomeUsuario=’macoratti’ and senhaUsuario=’123456′

Neste caso o usuário macoratti, senha 123456 será autenticado e terá acesso ao sistema. Tubo bem ?

Não , se você usa este tipo de instrução SQL nada esta bem pois o texto final da consulta SQL depende inteiramente do conteúdo das variáveis , e , se o conteúdo destas variáveis não for validado e tratado o texto final concatenado poderá ser um SQL adulterado através de uma injeção SQL.

Quer ver ? Vou começar pegando leve. Vamos supor que um hacker decidiu invadir sua página. Uma das primeiras coisas que ele pode fazer é tentar uma injeção SQL , e, vai começar verificando se você esta tratando o apóstrofe (aspa simples: ‘). Se você não sabe a presença de um caractere de apóstrofe (‘) no conteúdo de uma variável concatenada no SQL é usada para delimitar strings de texto. Então suponha que ele digite os seguintes dados nos campos nome e senha:

nome = tes’te
senha =

Se você não tratar o apóstrofe vai ocorrer um erro de SQL (incorrect Sintax) ,e , vendo isto o hacker vai ficar mais animado…

Agora vou pegar pesado. Suponha então que a seguir ele digite os seguintes dados

nome = ‘ ; drop table users–
senha =

Este comando irá excluir a tabela users (se ela existir). E se você pensa que é muito difícil o hacker adivinhar o nome da sua tabela vou mostrar mais abaixo que ele pode fazer isto de uma maneira simples. Isto é possível pois o caractere (;) indica o fim de uma consulta e o começo de outra em T-SQL , e , o caractere (–) no final da linha faz com que o scrpt ASP seja executada sem erro.

Continuando o ataque , ele pode também informar o seguinte :

nome = admin
senha = ‘ or 1=1–

veja como vai ficar a consulta SQL montada:

select count(*) from usuarios where nomeUsuario=’admin’ and senhaUsuario=” or 1=1–‘

Aqui a consulta irá verificar se o nome do usuário é admin e se senha é vazio ou 1 for igual a 1 ( o que é verdade) ; bingo, se existir um usuário admin ele entrou no seu sistema.

Ele pode também tentar o seguinte :

nome = ‘ or 1=1–
senha =

a consulta SQL montada será :

select count(*) from usuarios where nomeUsuario=” or 1=1 –‘ and senhaUsuario=”

e bingo , ele burlou o seu sistema.

O hacker pode também tentar o seguinte :

nome = ‘ OR “=’
senha = ‘ OR “=’

e a consulta SQL montada será :

select count(*) from usuarios where nomeUsuario=” OR “=” AND senhaUsuario=” OR “=”

a consulta agora esta fazendo a comparação : OR “=” que é sempre verdadeira. Bingo ele entrou no seu site.

Para saber o nome das tabelas e campos o hacker pode fazer o seguinte :

nome = ‘ having 1=1–
senha =

isto pode causar o seguinte erro:

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e14’

[Microsoft] [ODBC SQL Server Driver] [SQL Server] Column ‘usuarios.codigo’ is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.

/login.asp , line 28

e bingo , o hacker agora sabe que o nome da tabela é usuarios e o nome do campo relacionado no formulário como nome é codigo.

E então , o que você acha que ele vai fazer ? Fazer a mesma coisa para o campo senha e então ele vai saber o nome da tabela e dos campos relacionados ao formulário. Imagine o estrago que ele não será capaz de fazer agora…

Pensa que ele pode ficar somente nisto. Já conhecendo o nome da tabela e das colunas se o hacker quiser saber o tipo de dados do campo ele pode fazer o seguinte :

nome = ‘ UNION SELECT SUM(nomeUsuario) FROM usuarios–
senha =

como o SQL Server vai tentar aplicar a cláusula SUM antes de determinar se o número dos campos nas duas colunas é igual. Ao tentar fazer um SUM em um campo texto o sistema pode emitir a seguinte mensagem de erro:

Microsoft OLE DB Provider for ODBC Drivers error ‘80040e7’

[Microsoft] [ODBC SQL Server Driver] [SQL Server] The Sum or average aggregate operation cannot take a varchar data type as na argument.

/login.asp , line 109

e bingo de novo , ele agora sabe o tipo de dado do campo nomeUsuario.

Agora sabe o que ele vai fazer ? Vai inserir um usuário com nome senha para se logar , assim :

nome = ‘ ; INSERT INTO usuarios VALUES(‘hacker’,’111111′)–
senha =

e bingo , ele vai se logar como hacker e senha 111111.

Acho que com estes exemplos já deu para você perceber que você tem que cuidar com muito mais cuidado das suas instruções SQL .Tenha certeza de uma coisa : as possibilidades do hacker são muitas.

Fonte: www.macoratti.net

2 respostas para Evitando Injeção SQL (parte 2)

  1. Jhosef Marks disse:

    Para evitar tais tipos de ataques, basta substituir o ‘ por um outro caracter, o x por exemplo, isso já incapacita invasão por injeção sql, claro que também precisa-se tratar as urls, mas isso já é outro assunto…

    Bom artigo, para quem ta começando ajuda muito.

  2. MFedatto disse:

    A melhor solução é fazer o select apenas com o login do usuário e após o dado retornado verificar se a senha retornada no recordset é igual à senha fornecida.

    Convém utilizar StoredProcedure para permitir o uso de caracteres especiais na senha, utilizando o ADODB.Command para que o próprio driver de conexão faça a conversão dos caracteres para o SQL.

Deixe uma resposta

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 )

Imagem do Twitter

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

Foto do Facebook

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

Foto do Google+

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

Conectando a %s

%d blogueiros gostam disto: