Artigo faz parte da disciplina de "Segurança de Sistemas", do professor
Elgio Schlemer.
Aposto que você já leu por aí alguma notícia sobre algum ataque de 'SQL Injection' que gerou grandes danos a empresas e sistemas. É difícil determinar o motivo pelo qual as pessoas ainda têm suas aplicações atacadas por SQL Injection em 2016. Pode se levar em consideração a máxima da lei da oferta, ou seja, se ainda há ataques deste nível ainda há quem caia.
Mas afinal, o que é?
É uma técnica onde usuários maliciosos podem injetar comandos SQL em no seu banco de dados, via input do website. Os comandos injetados podem alterar a query que será realizada e comprometer a segurança de uma aplicação web.
Costuma-se dizer que é uma técnica tão ingênua e simples de ser aplicada que até uma criança de 3 anos poderia realizá-la, sério, 3 anos (
Hacking is child's play - SQL injection with Havij by 3 year old - YouTube). Diversas empresas famosas e faculdades do mundo todo já caíram neste ataque, como por exemplo: The Wall Street Journal, Microsoft, o próprio The Pirate Bay, até recentemente a britânica TalkTalk, teve 4 milhões de dados furtados em 2015 e até mesmo, pasmem, o site do MySQL.
Exemplificando
Exemplo em C#:
SqlCommand com = new SqlCommand("UPDATE Usuarios Set Idade = '" + txtIdade.Text + "'" + "WHERE Idade = @Idade", conn);
Suponhamos que no campo txtIdade o usuário tenha digitado:
0 where 1=0; drop database Sistema;
Já entendeu o estrago que isso faria certo? Não? Calma, ele só iria digitar uma cláusula qualquer e depois apagaria todo o banco de dados.
Normalmente as cláusulas injetadas com a técnica não são simplesmente sem finalidade, como o exemplo acima, é comum a inclusão de informações falsas, para conseguir acesso total a aplicação e alterar seu comportamento sem ser notado. Para esse caso, seria fácil se prevenir adicionando parâmetros para cada campo a ser modificado, restringindo a gama de possibilidades de texto livre:
com.Parameters.Add("@Idade", SqlDbType.Int);
Como evitar
Procurar por "como evitar SQL Injection em X linguagem" terá como resultado respostas parecidas, no geral, pode se resumir em parâmetros SQL. São valores que são adicionados à query em tempo de execução de uma maneira controlada, por exemplo:
txtUsuarioId = getRequestString("UsuarioId");
txtSQL = "SELECT * FROM Users WHERE UserId = @0";
db.Execute(txtSQL, txtUsuarioId);
Os parâmetros são representados com a marcação de '@'. O SQL valida cada parâmetro para validar que é o correto para cada coluna.
Outra técnica que pode ser utilizada é definindo a quantidade máxima de caracteres de cada campo texto. Desta forma garantimos que não serão inserido textos maiores do que o configurado. Campos de usuário e senha devem possuir este tipo de definição. Podemos também validar as entradas de texto bloqueando a utilização de certos caracteres e palavras utilizadas nas consultas SQL.
Aqui no próprio Viva o
Linux temos exemplos bem estruturados de como evitar e fazer este ataque em outras linguagens: