Como se proteger?
Todos os dados inputados por usuários não podem ser inputados diretamente em um SQL statement. Ao invés disso devem ser utilizadas queries parametrizadas, ou então os inputs devem ser cuidadosamente filtrados para verificar caracteres de escape.
Usando Queries Parametrizadas
Em linguagens de programação como Java e .NET, queries parametrizadas podem ser utilizadas para trabalhar com parâmetros (algumas vezes chamados de placeholders ou bind virables) ao invés de injetar o dado inputado diretamente na query. Em muitos casos, a query SQL é fixa. O dado inputado é então adicionado (limitado) a um parametro. Abaixo um exemplo usando Java e a API JDBC.
PreparedStatement prep = conn.prepareStatement("SELECT * FROM USERS WHERE USERNAME=? AND PASSWORD=?");
prep.setString(1, username);
prep.setString(2, password);
Usando Scaping
Essa é uma forma de tentar se previnir contra este tipo de ataque, porém algo que não se deve utilizar unicamente é filtrar caracteres perigosos. Um dos motivos pelos quais esse tipo de técnica não é a mais adequada é porque ela é baseada na criação de uma “lista negra” de caracteres que podem ser perigosos se inseridos em uma query SQL. Sendo assim, qualquer caracter perigoso que esteja fora de sua lista, irá ser executado. No PHP, por exemplo, existe uma função chamada mysql_real_escape_string que faz esta limpeza e pode ser utilizada para sanitizar seus inputs antes de envialos para uma query SQL:
$query = sprintf("SELECT * FROM Users where UserName='%s' and Password='%s'",
mysql_real_escape_string($Username),
mysql_real_escape_string($Password));
mysql_query($query);
Abaixo segue um exemplo de uma função de escaping customizada baseada em um filtro de SQL injection.
$title = $_POST['title']; // dado inputado pelo site
$description = $_POST['description']; // dado inputado pelo site
// Definindo a lista
$dirtystuff = array("\"", "\\", "/", "*", "'", "=", "-", "#", ";", "<", ">", "+", "%");
$title = str_replace($dirtystuff, "", $title); // Funcionou!
$description = str_replace($dirtystuff, "", $description); // Funcionou!
// input: I\ "like/ green<** veg'et=a-bles> ;and< pizza**
// output: I like green vegetables and pizza
// input: a';DROP TABLE users; SELECT * FROM data WHERE name LIKE '%
// output: aDROP TABLE users SELECT FROM data WHERE name LIKE
?>
Finalizando, existem muitas outras formas de se prevenir contra ataques de SQL Injection, porém a mais importante ainda depende dos programadores aumentarem seu conhecimento sobre segurança, aplicando a seus códigos.
Diretor de Operações da In2Sec (Itelligence to Security), é formado em Análise de Sistemas com MBA em Gestão de Riscos, atuou em diversas empresas nacionais e multinacionais, no Brasil e exterior. Especialista em Gestão de Riscos e Segurança da Informação, é responsável pelas operações das Américas da Certificadora TrustSign e das Consultorias de Segurança e-Horus e A.