Hospedagem de Sites Profissional e de Alta Performance

Proteção Contra SQL Injection: O Que Você Precisa Saber

Table of Contents

SQL Injection é uma das falhas mais exploradas na web. Ela permite que invasores manipulem consultas SQL e acessem dados sigilosos. A boa notícia: é 100% evitável com práticas corretas. Nesse artigo você verá:

  1. O que é SQL Injection e como acontece
  2. Erros comuns em WordPress e PHP
  3. Entrada segura: validação e saneamento
  4. Prepared Statements no WordPress
  5. Prepared Statements em PHP (PDO/MySQLi)
  6. Hardening no servidor e no banco
  7. Como detectar e responder a incidentes
  8. Checklist rápido de prevenção
  9. FAQ e tags de referência

1) O que é SQL Injection e como acontece

O ataque ocorre quando dados do usuário entram na query sem preparo. O atacante injeta comandos e altera o resultado. O impacto vai de vazamento a exclusão total do banco.

2) Erros comuns em WordPress e PHP

  • Concatenar variáveis diretamente na SQL. Evite sempre.
  • Confiar apenas em esc_sql(). Ela não substitui prepare.
  • Falta de nonce e checagem de capabilities em AJAX/REST.
  • Campos numéricos tratados como texto. Tipagem importa.

3) Entrada segura: validação e saneamento

  • Valide por whitelist (valores permitidos). É mais seguro.
  • Tipagem: use absint(), intval(), floatval().
  • Strings: sanitize_text_field() e sanitize_email().
  • Arquitetura: valide no backend mesmo que o frontend valide.

4) Prepared Statements no WordPress

Use $wpdb->prepare() para toda SQL dinâmica. A engine faz o escape correto por tipo.

4.1) SELECT seguro


// Exemplo seguro com $wpdb->prepare()
global $wpdb;
$post_id = absint($_GET['id'] ?? 0);
$sql = $wpdb->prepare(
  "SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key = %s",
  $post_id,
  '_minha_chave'
);
$valor = $wpdb->get_var($sql);

4.2) INSERT/UPDATE seguros


global $wpdb;
$dados = [
  'user_id'   => get_current_user_id(),
  'comentario'=> sanitize_text_field($_POST['comentario'] ?? '')
];
$format = ['%d','%s'];
$wpdb->insert("{$wpdb->prefix}comentarios", $dados, $format);

// UPDATE
$wpdb->update(
  "{$wpdb->prefix}comentarios",
  ['comentario' => $dados['comentario']],
  ['user_id' => $dados['user_id']],
  ['%s'], ['%d']
);

4.3) NUNCA faça assim


// Vulnerável. Não concatene entrada do usuário.
$busca = $_GET['q'] ?? '';
$sql = "SELECT * FROM {$wpdb->posts} WHERE post_title LIKE '%$busca%'";
$linhas = $wpdb->get_results($sql);

5) Prepared Statements em PHP (PDO/MySQLi)

5.1) PDO


$pdo = new PDO($dsn, $user, $pass, [
  PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
  PDO::ATTR_EMULATE_PREPARES => false
]);

$stmt = $pdo->prepare("SELECT * FROM clientes WHERE email = :email AND status = :status");
$stmt->execute([
  ':email' => filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL),
  ':status' => 'ativo'
]);
$cliente = $stmt->fetch(PDO::FETCH_ASSOC);

5.2) MySQLi


$mysqli = new mysqli($host, $user, $pass, $db);
$stmt = $mysqli->prepare("SELECT id, nome FROM pedidos WHERE id = ?");
$id = (int)($_GET['id'] ?? 0);
$stmt->bind_param("i", $id);
$stmt->execute();
$result = $stmt->get_result();

6) Hardening no servidor e no banco

  • Princípio do menor privilégio: o usuário do banco só precisa de grants mínimos.
  • Desative exibição de erros em produção. Logue em arquivo seguro.
  • Ative WAF e regras anti‑injection. ModSecurity, Cloudflare/WAF e firewall de aplicação ajudam.
  • Bloqueie execução PHP em /uploads. Separe credenciais por ambiente.
  • Rotacione senhas e use variáveis de ambiente (wp-config.php limpo).

7) Como detectar e responder a incidentes

  • Monitore logs de acesso e de queries lentas. Padrões de ' OR '1'='1 são suspeitos.
  • Audite endpoints admin-ajax.php e REST personalizados. Cheque nonce e capabilities.
  • Reveja alterações recentes no repositório/deploy. Busque concatenações em SQL.
  • Ao confirmar o incidente: isole o site, troque credenciais e aplique patch imediato.

8) Checklist rápido de prevenção

  • Usa prepare() em toda query dinâmica.
  • Valida e tipa entradas no backend.
  • Nonce + current_user_can() em AJAX/REST.
  • Usuário do banco com privilégios mínimos.
  • Erros ocultos e logs ativos.
  • WAF e bloqueio de PHP no /uploads.
  • Revisão de código antes de cada release.

Perguntas Frequentes (FAQ)

O que é SQL Injection?

É a inserção de comandos SQL maliciosos em entradas do sistema. O objetivo é manipular ou ler dados sem permissão.esc_sql() resolve o problema?

Não sozinho. Use $wpdb->prepare(). Ela garante o tipo e a posição corretos dos parâmetros.Preciso validar dados mesmo usando prepare?

Sim. Prepare previne injeção, não regra de negócio. Valide tipos, formatos e limites.Como proteger AJAX e REST no WordPress?

Exija nonce válido e verifique current_user_can(). Aplique prepare() em queries internas.WAF substitui prepared statements?

Não. WAF é camada extra. Prepared statements são obrigatórios na aplicação.

Tags

WordPress, Segurança, SQL Injection, Prepared Statements, $wpdb, PDO, MySQLi, WAF, Hardening, Server Express

O QUE NOSSOS CLIENTES ESTÃO DIZENDO?

Velocidade e Confiabilidade, para o seu Site Decolar!

Fale conosco

Negócio Digital Color White