Desenvolvimento de Software
Seguro
Aula 5 – SQL Injection
https://sites.google.com/site/thiagoaalves/
O que é?
Uma ameaça de segurança que aproveita
de falhas em sistemas web (na sua
maioria), interagindo com as bases de dados.
O que é?
A forma mais conhecida de ataques e
chamada de SQL Injection( Injeção SQL).
O nome vem da utilização do código SQL
para realização de ações nocivas dentro do sistema.
O que é?
Injeção SQL é um ataque no qual um
código mal-intencionado é inserido em cadeias de caracteres que são passadas posteriormente para uma instância do servidor SQL.
O que é?
Qualquer procedimento que construa
instruções SQL deve ser verificado quanto a vulnerabilidades de injeção
porque o servidor SQL executará todas as consultas sintaticamente válidas que receber. Mesmo dados com parâmetros podem ser manipulados por um invasor qualificado e determinado.
SQL Injection
SQL Injection
A forma principal de injeção SQL consiste
em inserção direta de código em variáveis de entrada de usuário, concatenadas com comandos SQL e executadas.
SQL Injection
O processo de “injeção” encerra
prematuramente uma cadeia de
caracteres de texto e anexa um novo comando.
O comando inserido na injeção pode
apresentar cadeias de caracteres
adicionais anexadas a ele antes de ser executado.
SQL Injection
Quando as cadeias de caracteres
armazenadas são concatenadas
subsequentemente em um comando SQL dinâmico, o código mal-intencionado é
SQL Injection
O Principal perigo desta técnica, e a
possibilidade de subverter um banco de dados que um atacante, possa realizar as seguinte tarefas:
◦ Inserção de Dados/Tabelas;
◦ Remoção de Dados/Tabelas;
◦ Recuperação de informações sensíveis, não só do banco mas do sistema.
SQL Injection
Reflexão:
Dos problemas apresentados no slide
anterior quais podem ser as
consequências nas bases de dados. A quais perigos você esta suscetível.
SQL Injection – Exemplo
Agora vamos ver um exemplo simples de
como e utilizada a SQL Injection.
A linguagem de programação utilizada no
exemplo foi ASP, e o servidor de banco de dados e SQL Server.
O Passo a Passo foi consultado no seguinte site: http://www.macoratti.net/sql_inj.htm
SQL Injection – Exemplo
Geralmente quando o usuário clicar no
botão - Enviar - o script será executado para efetuar a validação dos dados
informados.
Abaixo temos um script típico para um
SQL Injection – Exemplo
<%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 & "'"
. . .
SQL Injection – Exemplo
. . .
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
SQL Injection – Exemplo
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. Vamos supor também que este seja um usuário cadastrado e valido dentro do sistema.
Ao informar o nome e a senha e clicar no
botão Enviar o script do arquivo será
executado. Vamos ver como ficou a instrução SQL montada neste caso :
SQL Injection – Exemplo
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.
SQL Injection – Exemplo
Pergunta:
Este código e confiável e seguro? Resposta:
Não , se você usa este tipo de instrução SQL o
texto final da consulta 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 poderá ser um SQL adulterado.
SQL Injection – Exemplo
Agora vamos pensar no seguinte cenário, 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
SQL Injection – Exemplo
Se você não tratar o caso da apóstrofe vai
ocorrer um erro de SQL (incorrect Sintax).
SQL Injection – Exemplo
Agora vamos supor que ele descobriu
que o seu código não tem o devido
tratamento, então sua próxima tentativa vai ser a seguinte:
nome = ' ; drop table users--senha =
SQL Injection – Exemplo
O que vai acontecer?
O comando irá excluir a tabela users (se
ela existir).
Mas qual o Problema?
SQL Injection – Exemplo
Só com este pequeno teste de tentar
inserir as aspas simples e tentar apagar uma única tabela do seu sistema já vai mostrar uma grande vulnerabilidade.
Isto é possível pois o caractere (;) indica
o fim de uma linha e o começo de outra em T-SQL , e o caractere (--) no final da linha faz com que o script seja executada sem erro.
SQL Injection – Exemplo
Outra coisa que ele pode tentar fazer
para acessar o sistema.
Ele pode informar os seguintes dados : 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--'
SQL Injection – Exemplo
Aqui a consulta irá verificar se existe um
usuário com nome de admin e se senha é vazio ou 1 for igual a 1 ( o que é
verdade)
Se existir um usuário admin ele entrou no
SQL Injection – Exemplo
Para tentar descobrir o nome das tabelas e
campos o atacante pode tentar 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.
SQL Injection – Exemplo
Com esta entrada consegue se descobrir
o nome da tabela que é usuários e o nome do campo relacionado no
SQL Injection – Exemplo
De posse desta informação ele vai fazer o
mesmo para tentar descobrir o campo de senha.
Já conhecendo o nome da tabela e das
colunas se ele quiser saber o tipo de dados do campo ele pode tentar a seguinte operação:
SQL Injection – Exemplo
nome = ' UNION SELECT SUM(nomeUsuario) FROM
SQL Injection – Exemplo
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.
SQL Injection – Exemplo
Com isso ele consegue descobrir o tipo
de dado de nomeUsuario.
E o que ele pode fazer com essa
informação?
SQL Injection – Exemplo
Sabendo o nome da tabela, e os campos para logar
ele pode facilmente se inserir dentro da base de dados:
nome = ' ; INSERT INTO usuarios
VALUES('hacker','111111')--senha =
Com isso ele consegue burlar o código de cadastro e
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 são muitas.
Como Evitar ataques por SQL
Injection
A Principal forma de se evitar uma SQL
Injection e onde muitos esquecem:
Como Evitar ataques por SQL
Injection
Uma abordagem tradicional para a
prevenção de ataques é lidar com eles como um problema de validação de
entrada e aceitar apenas caracteres de valores seguros ou identificar e escapar de valores potencialmente maliciosos.
Como Evitar ataques por SQL
Injection
Opte sempre por instruções SQL
parametrizadas, elas exigem menos manutenção e podem oferecer mais
garantias no que diz respeito à segurança, contramedidas, tais como limitações de privilégio para o servidor de banco de
dados e assim por diante. Outros pontos para se verificar são:
Como Evitar ataques por SQL
Injection
◦ Inspecionar todos os pontos de entrada para não permitir o uso de meta-caracteres;
◦ Caso necessite utilizar meta-caracteres, utilize de mecanismos para protegê-los de maneira correta. Existem diversas funções que realizam o
procedimento de escapar caracteres para evitar que eles sejam interpretados de maneira não apropriada pelo aplicativo web.
◦ Utilize, quando possível, funções específicas de banco como stored procedures, que apesar de também serem vulneráveis à ataques de injeção de SQL possuem a condição de evitar exposição exagerada da lógica da aplicação e limitar os tipos de parâmetros recebidos do usuário.
Como Evitar ataques por SQL
Injection
Valide todas as Entradas:
Sempre valide entrada de usuário
testando tipo, comprimento, formato e intervalo. Quando você estiver
implementando precauções contra
entrada mal-intencionada, considere os cenários de arquitetura e implantação de seu aplicativo.
Como Evitar ataques por SQL
Injection
Lembre-se de que programas projetados
para executar em um ambiente seguro podem ser copiados para um ambiente sem segurança. As sugestões seguintes devem ser consideradas práticas
Como Evitar ataques por SQL
Injection
Não faça suposições sobre o tamanho, o
tipo ou o conteúdo dos dados recebidos pelo seu aplicativo. Sempre faça os
seguintes questionamentos :
◦ Como seu aplicativo se comportará se um usuário errôneo ou mal-intencionado inserir um arquivo MPEG de 10 megabytes onde seu aplicativo espera um código postal?
◦ Como seu aplicativo se comportará se uma instrução DROP TABLE for incorporada em um campo de texto?
Como Evitar ataques por SQL
Injection
Teste o tamanho e tipo de dados de
entrada e imponha limites apropriados.
Teste o conteúdo de variáveis de cadeia
de caracteres e só aceite valores esperados. Rejeite entradas que
contenham dados binários, sequê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.
Como Evitar ataques por SQL
Injection
Quando você estiver trabalhando com
documentos XML, valide todos os dados em seu esquema à medida que são
inseridos.
Nunca construa instruções Transact-SQL
diretamente da entrada do usuário.
Use procedimentos armazenados para
Como Evitar ataques por SQL
Injection
Em ambientes de várias camadas, todos os
dados devem ser validados antes de
serem admitidos à zona de confiança. Os dados que não passam pelo processo de validação devem ser rejeitados e um erro deve ser retornado à camada anterior.
Como Evitar ataques por SQL
Injection
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.
Sempre que puder, rejeite entrada que contenha os caracteres a seguir.