Previna-se contra a Injeção SQL
Hoje eu vou mostrar como evitar a injeção SQL. |
A SQL - Structured Query Language - é largamente usada para interagir com banco de dados relacionais. Se você considerar que 90% das aplicações utilizam banco de dados com suporte a SQL vai concluir que o uso da SQL é quase uma unanimidade por ser prática , fácil e portátil.
Em se falando de aplicações Web temos uma grande utilização de banco de dados para armazenar as mais diversas informações : endereços e documentos pessoais , contas e valores financeiros , números de cartões de crédito , dados empresariais , etc.
Ao colocar sua aplicação na Web você a esta expondo a um acesso mais amplo e indiscriminado. Afinal qualquer um que tenha acesso a url do site terá acesso a sua aplicação e aos dados que ela disponibiliza. Pensando na segurança de suas informações as empresas investem pesado em firewalls , certificação digital e outros recursos , com o objetivo de se proteger de invasores.
Para que o controlar o acesso as informações normalmente restringe-se o acesso aos usuários cadastrados usando um nome e senha para identificação ; estes dados são colhidos através de um formulário de login e são então verificados com as informações armazenadas em um banco de dados dos usuários cadastrados; se estiverem corretas o acesso é permitido caso contrário o acesso é negado.
É assim que funciona o home banking na internet e uma infinidade de outras aplicações web na qual o acesso é restrito.
Você pode ter o aparato mais moderno em termos de tecnologia de segurança protegendo o seu site de um ataque hacker e nem se dar conta de que a vulnerabilidade da sua aplicação esta ali naquele formulário de login. Ele pode ser a porta de entrada para ataques maliciosos através da injeção de SQL.
A injeção SQL ocorre quando um invasor consegue inserir comandos SQL na instrução SQL que você usa no seu script de modo a burlar a restrição e ter acesso ou danificar as informações armazenadas no seu banco de dados.
Neste artigo eu vou mostrar como a injeção de SQL ocorre e falar sobre algumas das medidas que você pode tomar para evitá-la. Embora as informações sejam focadas em páginas ASP e banco de dados SQL Server /Access elas se aplicam a qualquer script e banco de dados que usam um dialeto SQL.
Como ocorre a injeção SQL
Se você acha que não deve levar a sério a injeção SQL veja esta notícia da INFO:
500 mil sites sofrem injeção de SQLSexta-feira, 25 de abril de 2008 - 12h54
SÃO PAULO – 500 mil sites foram
afetados por uma injeção de SQL que propaga um cavalo-de-tróia ladrão de
senhas.
Segundo o Sans Institute Storm Center, SISC, os ataques atingiram sites de entidades, de empresas e até páginas de governo. “Esse tipo de injeção esvazia o conceito de site ‘confiável’ ou ‘seguro’ ”, diz o pesquisador Donald Smith, do SISC. Os sites comprometidos com essa injeção de SQL são invadidos por um código que redireciona o browser para outro site, no qual um cavalo-de-tróia ladrão de senhas tenta se instalar na máquina do usuário. O SISC recomenda que as empresas bloqueiem em seus firewalls de borda o acesso ao endereço hxxp:/www.nihaorr1.com e também ao IP a ele associado, 219DOT153DOT46DOT28 veja também esta notícia: http://www.linhadefensiva.org/2008/05/ataques-de-sql-injection-atingem-sites-brasileiros/ |
500 mil sites !!!! Você gostaria que o seu estive entre um deles ??? Então continue a ler...
Abaixo temos um típico formulário de login :
form
name="frmLogin" action="login.asp" method="post"> |
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:
<%
|
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.
Como evitar uma ataque de injeção SQL
A seguir algumas orientações de como você pode evitar um ataque de injeção SQL :
1- Estabeleça uma política de segurança rígida e criteriosa limitando o acesso dos seus usuários. Isto quer dizer que você deve dar somente os poderes necessários aos seus usuários. Não de acesso de escrita a tabelas e dê somente acesso as tabelas que o usuário vai precisar.
2- Faça a validação da entrada de dados no formulário e não permita os caracteres inválidos como : (') , (--) e (;) nem de palavras maliciosas como insert , drop , delete, xp_ . Abaixo algumas funções que você pode usar:
- Substituindo o apóstrofe(') pelo duplo apóstrofe ('')
<%
Function ExpurgaApostrofe(texto) %> |
- Substituindo os caracteres e palavras maliciosas por vazio("").
<% Function LimpaLixo( input ) dim lixo lixo = array ( "select" , "drop" , ";" , "--" , "insert" , "delete" , "xp_") textoOK = input for i
= 0 to uBound(lixo) LimpaLixo = textoOK end Function |
- Rejeitando os dados maliciosos:
<% Function ValidaDados( input ) lixo = array ( "select" , "insert" , "update" , "delete" , "drop" , "--" , "'") ValidaDados = true
for i = lBound (lixo) to ubound(llixo) |
Sempre que puder, rejeite entrada que contenha os caracteres a seguir.
Caractere de entrada | Significado em Transact-SQL |
---|---|
; | Delimitador de consulta. |
' | Delimitador de cadeia de dados de caractere. |
-- | Delimitador de comentário. |
/* ... */ | Delimitadores de comentário. Texto entre / * e * / não é avaliado pelo servidor. |
xp_ | Usado no início do nome de procedimentos armazenados estendidos de catálogo, como xp_cmdshell. |
3- Limite a entrada de texto para o usuário no formulário de entrada de dados. Se o campo nome deve ter somente 10 caracteres restrinja a isto a entrada de dados no formulário. O mesmo vale para a senha;
4- Faça o tratamento adequado de erros não permitindo que mensagens de erros exponham informações sobre a estrutura dos seus dados;
5- Faça um log para auditoria dos erros ocorridos e das operações mais importantes da aplicação;
6- Sempre valide entrada de usuário testando tipo, comprimento, formato e intervalo;
7- Nunca construa instruções SQL ou Transact-SQL diretamente da entrada do usuário;
8- Use procedimentos armazenados (stored Procedures) para validar entrada de usuário;
9- Nunca concatene entrada de usuário que não seja
validada. A concatenação de cadeia de caracteres é o ponto principal de entrada
de injeção de script;
10 - Teste o conteúdo de variáveis de cadeia de caracteres e só aceite valores
esperados. Rejeite entradas que contenham dados binários, seqüências de escape e
caracteres de comentário. Isso pode ajudar a impedir injeção de script e
proteger contra explorações de excesso de buffer;
A Microsoft lançou um
kit de ferramentas que pretende auxiliar desenvolvedores e administradores
de websites a bloquear e erradicar a recente onda de ataques de
SQL Injection (Injeção SQL). As ferramentas, que são voltadas para desenvolvedores web e administradores de TI, buscam auxiliar a identificação de pontos frágeis em scripts ASP que poderiam ser explorados em um ataque de injeção SQL. As ferramentas são: Scrawlr - Examina os arquivos do site e simultaneamente analisa os parâmetros usados em cada página buscando por vulnerabilidades do injeção SQL. Microsoft Source Code Analyzer for SQL Injection - Chamada de MSCASI, esta é uma ferramenta de análise estática para análise dos códigos em ASP. Para executá-la é necessário ter acesso ao código fonte da página. URLScan 3.1 - Esta ferramenta restringe os tipos de solicitações HTTP que o IIS (Internet Information Services) irá processar. Ao bloquear alguns tipos específicos de solicitações, a ferramenta pode prevenir certos ataques. |
Segurança é coisa séria e vale a pena tomar todas as precauções ao nosso alcance para preservar nossos dados e nossos empregos.....
Até breve...
Referências: