Tutorial SQL

SQL INÍCIO Introdução SQL Sintaxe SQL Seleção SQL SQL Select Distinto SQL Onde SQL E, Ou, Não Ordem SQL por SQL Inserir em Valores Nulos SQL Atualização SQL Excluir SQL SQL Select Top SQL Mínimo e Máximo Contagem SQL, Média, Soma Como SQL Curingas SQL Entrada SQL SQL entre Alias ​​SQL Junções SQL SQL Inner Join SQL Left Join Associação à direita do SQL Associação completa SQL Auto-junção SQL União SQL SQL Agrupar por SQL tendo SQL existe SQL Qualquer, Todos SQL Selecionar em SQL Inserir na seleção Caso SQL Funções Nulas SQL Procedimentos armazenados SQL Comentários SQL Operadores SQL

Banco de dados SQL

SQL Criar banco de dados SQL Drop DB Banco de dados de backup SQL SQL Criar Tabela Tabela de descarte de SQL Tabela de alteração SQL Restrições SQL SQL não nulo SQL exclusivo Chave Primária SQL Chave estrangeira SQL Verificação SQL Padrão SQL Índice SQL Incremento automático de SQL Datas SQL Visualizações SQL Injeção SQL Hospedagem SQL Tipos de dados SQL

Referências SQL

Palavras-chave SQL Funções do MySQL Funções do SQL Server Funções de acesso MS Referência Rápida SQL

Exemplos SQL

Exemplos SQL Teste SQL Exercícios de SQL Certificado SQL

Injeção de SQL


Injeção SQL

A injeção de SQL é uma técnica de injeção de código que pode destruir seu banco de dados.

A injeção de SQL é uma das técnicas de hacking mais comuns na web.

A injeção de SQL é a colocação de código malicioso em instruções SQL, por meio de entrada de página da web.


SQL em páginas da Web

A injeção de SQL geralmente ocorre quando você solicita a entrada de um usuário, como seu nome de usuário/id de usuário e, em vez de um nome/id, o usuário fornece uma instrução SQL que você executará inadvertidamente em seu banco de dados.

Veja o exemplo a seguir que cria uma SELECTinstrução adicionando uma variável (txtUserId) a uma string de seleção. A variável é buscada na entrada do usuário (getRequestString):

Exemplo

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

O restante deste capítulo descreve os perigos potenciais de usar a entrada do usuário em instruções SQL.


SQL Injection Baseado em 1=1 é Sempre Verdadeiro

Observe o exemplo acima novamente. O objetivo original do código era criar uma instrução SQL para selecionar um usuário, com um determinado ID de usuário.

Se não houver nada que impeça um usuário de inserir uma entrada "errada", o usuário pode inserir alguma entrada "inteligente" como esta:

ID do usuário:

Então, a instrução SQL ficará assim:

SELECT * FROM Users WHERE UserId = 105 OR 1=1;

O SQL acima é válido e retornará TODAS as linhas da tabela "Usuários", pois OR 1=1 é sempre TRUE.

O exemplo acima parece perigoso? E se a tabela "Usuários" contiver nomes e senhas?

A instrução SQL acima é muito parecida com esta:

SELECT UserId, Name, Password FROM Users WHERE UserId = 105 or 1=1;

Um hacker pode obter acesso a todos os nomes de usuário e senhas em um banco de dados, simplesmente inserindo 105 OR 1=1 no campo de entrada.



SQL Injection com base em ""="" é sempre verdadeiro

Aqui está um exemplo de login de usuário em um site:

Nome do usuário:

Senha:

Exemplo

uName = getRequestString("username");
uPass = getRequestString("userpassword");

sql = 'SELECT * FROM Users WHERE Name ="' + uName + '" AND Pass ="' + uPass + '"'

Resultado

SELECT * FROM Users WHERE Name ="John Doe" AND Pass ="myPass"

Um hacker pode obter acesso a nomes de usuário e senhas em um banco de dados simplesmente inserindo " OR ""=" na caixa de texto de nome de usuário ou senha:

Nome do usuário:

Senha:

O código no servidor criará uma instrução SQL válida como esta:

Resultado

SELECT * FROM Users WHERE Name ="" or ""="" AND Pass ="" or ""=""

O SQL acima é válido e retornará todas as linhas da tabela "Users", pois OR ""="" é sempre TRUE.


Injeção de SQL com base em instruções SQL em lote 

A maioria dos bancos de dados oferece suporte à instrução SQL em lote.

Um lote de instruções SQL é um grupo de duas ou mais instruções SQL, separadas por ponto e vírgula.

A instrução SQL abaixo retornará todas as linhas da tabela "Usuários" e excluirá a tabela "Fornecedores".

Exemplo

SELECT * FROM Users; DROP TABLE Suppliers

Observe o seguinte exemplo:

Exemplo

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

E a seguinte entrada:

ID do usuário:

A instrução SQL válida ficaria assim:

Resultado

SELECT * FROM Users WHERE UserId = 105; DROP TABLE Suppliers;

Usar parâmetros SQL para proteção

Para proteger um site da injeção de SQL, você pode usar parâmetros SQL.

Parâmetros SQL são valores que são adicionados a uma consulta SQL em tempo de execução, de forma controlada.

Exemplo de Razor ASP.NET

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = @0";
db.Execute(txtSQL,txtUserId);

Observe que os parâmetros são representados na instrução SQL por um marcador @.

O mecanismo SQL verifica cada parâmetro para garantir que esteja correto para sua coluna e seja tratado literalmente, e não como parte do SQL a ser executado.

Outro exemplo

txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
db.Execute(txtSQL,txtNam,txtAdd,txtCit);

Exemplos

Os exemplos a seguir mostram como criar consultas parametrizadas em algumas linguagens comuns da Web.

SELECIONE A DECLARAÇÃO NO ASP.NET:

txtUserId = getRequestString("UserId");
sql = "SELECT * FROM Customers WHERE CustomerId = @0";
command = new SqlCommand(sql);
command.Parameters.AddWithValue("@0",txtUserId);
command.ExecuteReader();

INSERIR NA DECLARAÇÃO NO ASP.NET:

txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
command = new SqlCommand(txtSQL);
command.Parameters.AddWithValue("@0",txtNam);
command.Parameters.AddWithValue("@1",txtAdd);
command.Parameters.AddWithValue("@2",txtCit);
command.ExecuteNonQuery();

INSERIR NA DECLARAÇÃO EM PHP:

$stmt = $dbh->prepare("INSERT INTO Customers (CustomerName,Address,City)
VALUES (:nam, :add, :cit)");
$stmt->bindParam(':nam', $txtNam);
$stmt->bindParam(':add', $txtAdd);
$stmt->bindParam(':cit', $txtCit);
$stmt->execute();