SQL Injection: o que é, como detectar e como prevenir

SQL Injection é uma das vulnerabilidades mais antigas e devastadoras da web. Saiba como identificar e proteger sua aplicação contra esse tipo de ataque.

O que é SQL Injection

SQL Injection (SQLi) ocorre quando um atacante consegue inserir ou manipular comandos SQL através de campos de entrada da aplicação (formulários, URLs, headers). Isso acontece quando a aplicação concatena dados do usuário diretamente em queries SQL sem sanitização ou parametrização.

Exemplo clássico de código vulnerável:

// VULNERÁVEL — nunca faça isso
const query = "SELECT * FROM users WHERE email = '" + userInput + "'";

// Um atacante pode enviar:
// ' OR '1'='1' --
// Resultado: SELECT * FROM users WHERE email = '' OR '1'='1' --'
// Isso retorna TODOS os usuários do banco de dados

Os principais tipos de SQL Injection são:

  • In-band (clássico): o resultado da injeção aparece diretamente na resposta da página.
  • Blind SQLi: o atacante infere dados observando diferenças no comportamento da aplicação (tempo de resposta, mensagens de erro).
  • Out-of-band: os dados são exfiltrados por canais alternativos (DNS, HTTP requests para servidor do atacante).

Por que é perigoso

SQL Injection é classificado como severidade crítica porque dá ao atacante acesso direto ao banco de dados:

  • Leitura de todos os dados do banco (senhas, emails, dados pessoais)
  • Modificação ou exclusão de registros
  • Bypass completo de autenticação
  • Escalação de privilégios (tornar-se admin)
  • Em alguns casos, execução de comandos no sistema operacional
  • Violação de LGPD com exposição de dados pessoais

Em 2023, mais de 30% dos data breaches reportados envolveram SQL Injection como vetor inicial de ataque. Uma única query vulnerável pode comprometer todo o banco de dados.

Como o SAFETAGGY detecta

O SAFETAGGY utiliza duas abordagens para detectar SQL Injection:

  • Varredura básica: testa parâmetros de formulários e URLs com payloads de sintaxe SQL, analisando diferenças nas respostas (mensagens de erro, tempos de resposta, conteúdo alterado).
  • Deep Scan (pentest IA): utiliza o sqlmap, a ferramenta de referência para detecção e exploração de SQL Injection, testando automaticamente múltiplas técnicas (boolean-based, time-based, error-based, UNION-based, stacked queries).

Faça uma varredura agora para verificar se seus endpoints estão vulneráveis.

Como corrigir

A regra de ouro: nunca concatene dados do usuário em queries SQL. Use sempre queries parametrizadas ou ORMs.

1. Prisma (ORM recomendado para Node.js)

Prisma utiliza queries parametrizadas por padrão. Todas as entradas são tratadas como dados, nunca como SQL:

// SEGURO — Prisma parametriza automaticamente
const user = await prisma.user.findUnique({
  where: { email: userInput },
});

// SEGURO — mesmo em queries complexas
const users = await prisma.user.findMany({
  where: {
    OR: [
      { name: { contains: searchTerm } },
      { email: { contains: searchTerm } },
    ],
  },
});

// CUIDADO — $queryRawUnsafe é vulnerável
// Use $queryRaw com template literals tagged:
const result = await prisma.$queryRaw`
  SELECT * FROM users WHERE email = ${userInput}
`;

2. pg (PostgreSQL nativo)

import { Pool } from 'pg';
const pool = new Pool();

// SEGURO — query parametrizada com $1, $2, etc.
const result = await pool.query(
  'SELECT * FROM users WHERE email = $1 AND active = $2',
  [userInput, true]
);

// VULNERÁVEL — concatenação direta
// const result = await pool.query(
//   "SELECT * FROM users WHERE email = '" + userInput + "'"
// );

3. mysql2 (MySQL)

import mysql from 'mysql2/promise';
const conn = await mysql.createConnection({ /* config */ });

// SEGURO — prepared statement com ?
const [rows] = await conn.execute(
  'SELECT * FROM users WHERE email = ? AND role = ?',
  [userInput, 'user']
);

4. Validação de entrada com Zod

Além de queries parametrizadas, valide o formato dos dados antes de usar:

import { z } from 'zod';

const loginSchema = z.object({
  email: z.string().email().max(255),
  password: z.string().min(8).max(128),
});

// Na API route
const parsed = loginSchema.safeParse(req.body);
if (!parsed.success) {
  return res.status(400).json({ error: 'Dados inválidos' });
}
// parsed.data.email é validado e tipado

Checklist de prevenção

  • Use sempre queries parametrizadas ou ORMs (Prisma, Drizzle, TypeORM)
  • Nunca concatene input do usuário em strings SQL
  • Valide e sanitize todos os inputs no servidor com Zod ou similar
  • Aplique princípio do menor privilégio no usuário do banco de dados
  • Desabilite mensagens de erro detalhadas em produção
  • Monitore logs de queries para padrões suspeitos
  • Use WAF (Web Application Firewall) como camada adicional

Teste seu site agora

O SAFETAGGY verifica automaticamente se seus endpoints estão vulneráveis a SQL Injection e outras dezenas de falhas de segurança. Resultado em menos de 60 segundos.

Fazer varredura gratuita