Guia de tecnologias

Como proteger seu banco de dados contra SQL Injection

6 min read Segurança Atualizado 27 Sep 2025
Proteja bancos de dados contra SQL Injection
Proteja bancos de dados contra SQL Injection

Diagrama de SQL Injection ilustrando entrada maliciosa sendo injetada em uma consulta e o impacto no banco de dados

O que é SQL Injection (definição curta)

SQL Injection é uma técnica de ataque em que comandos SQL maliciosos são inseridos em entradas de uma aplicação para manipular a consulta executada no banco de dados. Em uma linha: é tratar dados do usuário como código.

Por que isso é perigoso

  • Pode devolver dados sensíveis (ex.: credenciais, PII).
  • Pode modificar ou apagar tabelas inteiras.
  • Pode permitir elevação de privilégios ou execução remota em alguns cenários.

Importante: ataques funcionam apenas quando a aplicação constrói consultas SQL concatenando diretamente dados não confiáveis.

Como um ataque típico acontece

Um formulário de login que monta uma string SQL com os valores enviados pelo usuário é um alvo clássico. Exemplo vulnerável em PHP (não use em produção):

Se um atacante enviar ' OR 'a'='a no campo de senha, a condição se tornará sempre verdadeira e o acesso pode ser concedido sem credenciais válidas.

Principais vetores e variações

  • Error-based: o atacante força o banco a retornar mensagens de erro detalhadas para descobrir a estrutura do banco.
  • Union-based: usa UNION para combinar resultados e exfiltrar dados.
  • Blind SQL Injection: o atacante não recebe resultados diretos, mas infere dados por testes booleanos ou temporizadores.
  • Out-of-band: usa canais externos (DNS, HTTP) para extrair dados.

Estratégias de defesa (camadas)

A proteção eficaz usa várias camadas. Nenhuma técnica isolada é 100% segura.

1) Consultas parametrizadas (prepared statements) — prioridade

Prepared statements separam o código SQL dos dados do usuário. Use sempre que possível.

Exemplo com PDO (PHP) — recomendado:

prepare('SELECT * FROM users WHERE username = :username AND user_password = :password');
$stmt->execute([':username' => $_POST['username'], ':password' => $_POST['password']]);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>

Exemplo com MySQLi (PHP):

prepare('SELECT * FROM users WHERE username = ? AND user_password = ?');
$stmt->bind_param('ss', $_POST['username'], $_POST['password']);
$stmt->execute();
$result = $stmt->get_result();
?>

Exemplo em Python com psycopg2 (Postgres):

cur.execute('SELECT * FROM users WHERE username = %s AND user_password = %s', (username, password))

Observação: prepared statements tratam entradas como dados, não como parte do SQL, eliminando a maior parte das injeções.

2) Validação e sanitização de entradas

  • Validação: verifique tipo, tamanho, formato (whitelisting preferível). Ex.: e-mail deve corresponder a regex básica, IDs devem ser inteiros.
  • Sanitização: remova espaços em excesso, caracteres de controle, quebras de linha. Use com cautela — nunca confie só em escaping.
  • Evite construir SQL concatenando strings com dados do usuário.

Exemplo de validação simples em PHP:

if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
  // rejeitar entrada
}
$id = intval($_GET['id']); // força número inteiro

3) Escaping (quando necessário)

Escaping (ex.: mysqli_real_escape_string) pode reduzir risco, mas não substitui prepared statements. Útil em contexts legados onde prepared statements não são possíveis.

4) Princípio do menor privilégio (least privilege)

  • Cada aplicação/serviço deve usar uma conta de banco de dados com apenas os direitos necessários (SELECT, INSERT, UPDATE específicos), não a conta SA/root.
  • Separe contas para leitura e escrita quando aplicável.

Exemplo (Microsoft SQL Server):

deny select on sys.tables to sqldatabasepermit;
deny select on sys.packages to sqldatabasepermit;
deny select on sys.sysobjects to sqldatabasepermit;

5) Trate erros com cuidado

Não exponha mensagens de erro detalhadas ao usuário final — registros internos podem conter detalhes úteis para depuração, mas devem ser protegidos.

6) Camadas adicionais

  • ORM (Object-Relational Mapping): frameworks bem projetados reduzem risco ao gerar consultas seguras, mas verifique pontos onde consultas brutas são usadas.
  • Stored procedures: podem ajudar se parametrizadas corretamente; não use procedures que concatenam strings SQL internamente.
  • Web Application Firewall (WAF): filtro adicional para detectar padrões de ataque.

Arquiteturas, heurísticas e mental models

  • Mental model: pense em dados como toxina — sempre contenha-os com barreiras (validação, parametrização, privilégios mínimos).
  • Heurística: “Never trust user input” — trate tudo como hostil até provar o contrário.

Checklist rápido para desenvolvedores e DBAs

  • Todas as consultas que usam dados externos usam prepared statements.
  • Campos são validados por tipo, tamanho e formato (whitelist).
  • Contas de banco seguem princípio do menor privilégio.
  • Mensagens de erro amigáveis ao usuário; logs detalhados internos e protegidos.
  • Revisões de código e testes automatizados para injeção.
  • Monitoramento e alertas para atividades anômalas (padrões de consulta, longos tempos de execução).

Playbook de resposta a incidente (resumo)

  1. Isolar a aplicação/endpoint afetado.
  2. Reverter a partir de backup conhecido e limpo se houver corrupção de dados.
  3. Rodar análise forense: logs de aplicação, logs do banco, conexões recentes.
  4. Bloquear credenciais ou rotacionar chaves afetadas.
  5. Aplicar correções (ex.: converter consultas vulneráveis para prepared statements).
  6. Notificar stakeholders e, se aplicável, cumprir obrigações regulatórias.

Importante: mantenha backups imutáveis e registre táteis (audit logs) para investigação.

Quando as defesas podem falhar (contraexemplos)

  • Aplicação usa ORM mas permite SQL bruto concatenado em algumas rotas — risco persiste.
  • Prepared statements são usados, mas entradas usadas em cláusulas dinâmicas (ORDER BY, table names) são concatenadas sem validação.
  • Erros de configuração: conta do app tem privilégios elevados por erro operacional.

Testes e aceitação

Critérios de aceitação:

  • Todas as rotas que aceitam input externo passam em testes automatizados de injeção (SAST/DAST + fuzzing).
  • Sem mensagens de erro SQL detalhadas para usuários.
  • Contas com privilégios restringidos documentadas.

Casos de teste recomendados:

  • Teste booleano: injetar ' OR '1'='1 e garantir que não retorna dados indevidos.
  • Teste de union: injetar payloads com UNION e verificar bloqueio/nenhum dado sensível retornado.
  • Teste de tempo (blind): injetar operações que dormem (quando aplicável) e checar comportamento.

Maturidade: níveis rápidos

  • Nível 1 (Inicial): consultas concatenadas, pouca ou nenhuma validação.
  • Nível 2 (Intermediário): validação básica, alguns prepared statements, logs básicos.
  • Nível 3 (Maduro): prepared statements em toda a entrada, least privilege, WAF, testes automáticos SAST/DAST, resposta a incidente definida.

Perguntas frequentes (FAQ)

O escaping é suficiente para prevenir SQL injection?

Escaping reduz risco, mas não é tão robusto quanto prepared statements. Use escaping apenas em contextos legados; migre para prepared statements.

ORM elimina a necessidade de validar entradas?

Não. ORM ajuda, mas validação continua necessária para dados semânticos (ex.: tamanhos, formatos) e para evitar construção de SQL dinâmico inseguro.

Devo bloquear mensagens de erro do banco de dados?

Sim: mostre mensagens genéricas ao usuário e registre detalhes sensíveis em logs internos com acesso restrito.

Resumo final

SQL Injection continua sendo uma das ameaças mais comuns a aplicações que usam bancos relacionais. A defesa eficaz combina práticas de desenvolvimento seguro (prepared statements, validação por whitelist), arquitetura segura (least privilege, segregação de contas), proteção em camadas (WAF, ORM, stored procedures) e processos operacionais (testes, monitoramento, playbooks de incidente). Adote prepared statements como regra, valide tudo, minimize privilégios e teste continuamente.

Extras: papel por papel — checklist resumido

Desenvolvedor:

  • Usar prepared statements em todas as consultas.
  • Validar e higienizar entrada (whitelist).
  • Evitar SQL dinâmico.

DBA/Administrador:

  • Criar contas com privilégios mínimos.
  • Monitorar queries incomuns e logs de auditoria.

Equipe de Segurança:

  • Automação de SAST/DAST, pentests periódicos.
  • Configurar WAF e integrar alertas.
Autor
Edição

Materiais semelhantes

Como ver e excluir o histórico do YouTube
Privacidade

Como ver e excluir o histórico do YouTube

Instalar Asterisk: primeiro PBX passo a passo
Telefonia

Instalar Asterisk: primeiro PBX passo a passo

Corrigir Microsoft Store que não funciona
Guias Técnicos

Corrigir Microsoft Store que não funciona

Varredura e proteção de sites WordPress
Segurança

Varredura e proteção de sites WordPress

RSS para tópicos de fórum com Blogger
Tutoriais

RSS para tópicos de fórum com Blogger

Instalar OCS Inventory NG Server 2 no CentOS 5.5
Linux

Instalar OCS Inventory NG Server 2 no CentOS 5.5