SQL Injection (SQLi)

Vulnerabilidade que permite a um atacante interferir nas consultas (queries) que uma aplicação faz ao seu banco de dados. Geralmente permite visualizar dados que o atacante não seria capaz de ver normalmente.

Como a falha ocorre

A falha acontece quando a entrada fornecida pelo usuário é concatenada diretamente em uma string de consulta SQL, em vez de ser tratada como um dado isolado.

Tipos de SQL Injection

1. In-band SQLi (Classic)

O atacante utiliza o mesmo canal de comunicação para lançar o ataque e coletar os resultados.

  • Error-based: O atacante obtém informações sobre a estrutura do banco de dados através das mensagens de erro geradas pelo servidor.

  • Union-based: Utiliza o operador UNION para combinar o resultado da query legítima com resultados de uma query maliciosa injetada.

2. Inferential SQLi (Blind SQLi)

Neste tipo, nenhum dado é transferido diretamente para o atacante através da página web. O atacante reconstrói a estrutura do banco enviando payloads e observando a resposta do servidor.

  • Boolean-based: Baseia-se em analisar se a página responde de forma diferente para condições Verdadeiras ou Falsas.

  • Time-based: Baseia-se no tempo de resposta do servidor (ex: injetando comandos como SLEEP() para verificar se a condição é verdadeira).

3. Out-of-band SQLi

Ocorre quando o atacante não consegue utilizar o mesmo canal para visualizar os resultados e depende da capacidade do servidor de realizar requisições externas (como DNS ou HTTP) para enviar os dados para um servidor externo controlado pelo atacante.

Exemplos de Exploração

Bypass de Login

Injeção de uma condição sempre verdadeira para ignorar a verificação de senha.

  • Payload: ' OR 1=1 --

  • Resultado na query: SELECT * FROM users WHERE username = '' OR 1=1 --' AND password = '...'

Exfiltração de Dados (UNION)

Para descobrir o número de colunas: ' ORDER BY 1-- ' ORDER BY 2--

Para extrair dados de outras tabelas: ' UNION SELECT username, password FROM users--

Ganhando Shell (RCE via SQLi)

Se o banco de dados tiver permissão de escrita no sistema de arquivos, é possível criar uma shell PHP: ' UNION SELECT "<?php system($_GET['cmd']); ?>",2,3 INTO OUTFILE '/var/www/html/shell.php' --

Como Prevenir

1. Prepared Statements (Parameterized Queries)

É a defesa mais eficaz. Em vez de concatenar strings, o desenvolvedor define o código SQL primeiro e depois passa os inputs do usuário como parâmetros. O banco de dados trata o input estritamente como dado, e não como parte do comando executável.

2. Input Validation

Implementar listas brancas (allow-lists) para garantir que o input do usuário corresponde ao formato esperado (ex: apenas números para IDs).

3. Princípio do Menor Privilégio

O usuário do banco de dados que a aplicação utiliza deve ter apenas as permissões necessárias para funcionar, evitando permissões de super-usuário ou acesso a arquivos do sistema.