SQL Injection: como prevenir no backend começa separando o comando SQL dos dados enviados pelo usuário. A falha aparece quando o servidor concatena texto não confiável dentro da query, como um e-mail digitado no formulário. Este guia mostra quais camadas cortam o problema na raiz e quais só reduzem o estrago depois que ele já entrou.
SQL Injection: como prevenir sem deixar brechas
SQL Injection é uma falha em que o texto enviado pelo usuário vira parte do comando SQL executado pelo banco. Prevenir SQL Injection no backend significa manter dado e comando separados, restringir o que a aplicação pode executar e reduzir a exposição do servidor, nessa ordem de prioridade.
O cenário clássico aparece em um campo de e-mail. O servidor monta a consulta por concatenação e o atacante envia um valor que fecha as aspas, encerra a consulta e acrescenta outro comando, como apagar a tabela de usuários.
A OWASP, fundação de referência em segurança de aplicações, mantém SQL Injection entre as falhas de injeção mais conhecidas e detalha defesas específicas para ela.
Você tem três lugares distintos para agir: dentro do banco, dentro do código do seu backend e na borda da rede. Cada um cobre um pedaço, e nenhum sozinho resolve tudo.
Como funciona um ataque com drop table users
O ataque funciona porque o servidor entrega ao banco uma string que mistura comando e dado. Quando isso acontece, o atacante controla parte do SQL executado e ganha poderes que não deveria ter, como ler outras tabelas ou alterar o próprio saldo.
Considere um formulário que recebe e-mail e uma query montada assim:
select * from users where email = '<email>'
Se o campo receber um valor que fecha as aspas, encerra a instrução e adiciona outra, o banco passa a executar dois comandos. O primeiro continua normal; o segundo, drop table users, apaga a tabela.
Não existe lista fechada de comandos perigosos. Qualquer instrução que o usuário do banco tenha permissão de executar pode aparecer na injeção.
Query parametrizada e prepared statement resolvem o problema?
Sim, na maioria dos casos. As duas soluções separam, por contrato, o texto da consulta e os valores enviados pelo usuário. O banco recebe o comando já definido e trata o restante como dado, mesmo que o dado pareça SQL.
A OWASP recomenda consultas parametrizadas como primeira defesa, com prepared statements como implementação usual. No PostgreSQL, documentação oficial do banco, o comando PREPARE permite executar a mesma instrução várias vezes com parâmetros distintos.
Existem variações entre bancos e bibliotecas. Algumas aceitam parâmetros em qualquer posição, outras exigem que o SQL seja fixo antes do envio. Vale conferir o guia do seu driver.
Privilégio mínimo e procedures limitam o estrago
Aplicar privilégio mínimo ao usuário do banco limita o alcance de qualquer injeção. Se a conexão do servidor só pode fazer select, insert e delete em tabelas específicas, o comando drop table users nem chega a ser executado.
Esse cuidado também protege contra outros problemas. Se alguém tomar o servidor por SSH e disparar comandos a partir dele, o estrago será limitado pelas mesmas permissões do banco.
Procedimentos armazenados seguem a mesma linha: a aplicação chama uma rotina nomeada, e o banco executa apenas o que já estava escrito. Isso reduz o que o atacante consegue compor livremente.
Como bloquear SQL Injection no código do backend
O backend é o lugar mais eficiente para cortar a falha, porque é ali que a query é montada. Cada linguagem e framework traz um jeito nativo de passar parâmetros, e ORMs geralmente já fazem isso por padrão.
A lista abaixo organiza essa busca, começando pela própria ferramenta que você já usa.
- Verifique como o seu framework de backend lida com parâmetros de consulta na documentação oficial da linguagem que você usa. Os guias de Python e Node.js mostram a passagem de parâmetros como padrão.
2. Se você usa um ORM ou query builder, confirme se a ferramenta parametriza por padrão e quando ela aceita SQL bruto. Nesses casos, o risco aparece na hora em que você escreve SQL cru.
3. Se a sua biblioteca não oferece parâmetros, procure a alternativa mantida que oferece. Trocar de driver costuma ser mais barato que remendar concatenação.
Esse ajuste é o mais simples e costuma resolver o problema na origem, sem depender de nenhuma outra camada.
Validação de input com Zod ou schema substitui a correção?
Não. Validar entrada ajuda a manter o sistema consistente, mas não é suficiente contra injeção de SQL. Um texto perfeitamente válido pode carregar um comando perigoso.
Uma ferramenta como Zod, biblioteca de validação de schemas em TypeScript, usa expressões regulares internas para checar formatos. Você não controla cada regra nem sabe se aquela validação cobre o que o seu banco interpreta como comando.
Existem endereços de e-mail válidos que parecem estranhos, e campos de texto livre aceitam praticamente qualquer coisa. Validar que uma descrição de produto é texto não impede a injeção dentro desse texto.
Trate a validação como reforço de consistência, não como defesa principal.
O que um Web Application Firewall consegue fazer
Um Web Application Firewall, serviço de filtragem de tráfego HTTP, bloqueia requisições com padrões suspeitos antes que elas cheguem ao seu servidor. Ele reduz a exposição, mas não substitui a correção no código.
Um WAF pode deixar passar variações que não reconhece, e essa é uma característica esperada dele. A documentação do ModSecurity, mecanismo de segurança de código aberto do projeto OWASP, deixa claro que o ferramental é uma camada a mais.
Colocar um firewall na borda protege a aplicação de vários ataques além de SQL Injection. Como efeito colateral, ele intercepta parte das tentativas de injeção.
Ordem prática para corrigir uma falha encontrada
Quando você encontra uma injeção, comece pelo ponto mais próximo da query. Esta sequência reduz o risco rapidamente e evita depender de camadas que não cortam o problema na raiz.
| Ordem | Camada | O que fazer | Limite |
|---|---|---|---|
| 1 | Código do backend | Parametrizar consultas na ferramenta que você já usa | Exige revisar SQL cru escrito à mão |
| 2 | Permissões do banco | Restringir o usuário da aplicação ao mínimo | Não impede leitura indevida com as permissões existentes |
| 3 | Borda da rede | Adicionar WAF para filtrar tráfego | Não cobre todas as variações |
A ordem importa porque cada camada assume riscos diferentes. As duas primeiras cortam o problema na origem; a terceira reduz o volume de tentativas que chegam até você.
Perguntas frequentes sobre SQL Injection
- Query parametrizada e prepared statement são a mesma coisa? São conceitos próximos, mas não idênticos. A query parametrizada é o princípio de separar comando e dado; o prepared statement é uma implementação concreta que muitos bancos oferecem para executar a mesma instrução com parâmetros diferentes.
- Validar todos os campos com Zod resolve o problema? Não. A validação checa formato e tipo, e um valor válido pode conter sintaxe SQL quando concatenado. Um campo de descrição aceita texto livre e, mesmo assim, pode carregar uma injeção.
- ORMs eliminam SQL Injection por padrão? Na maioria dos casos, sim, porque parametrizam as consultas. Porém, quando você escreve SQL bruto dentro do ORM ou usa um query builder, a proteção depende de como essa consulta é montada. Confirme na documentação da ferramenta.
- Um WAF é suficiente sozinho? Não. O WAF filtra padrões conhecidos e cobre várias ameaças, mas nenhuma ferramenta garante 100% de detecção. Ele soma defesa, não substitui a correção no código.
- Por que limitar as permissões do usuário da aplicação? Porque reduz o dano possível quando algo falha. Com privilégio mínimo, o servidor só executa o que precisa, e um comando destrutivo injetado simplesmente não tem permissão para rodar.
- Qual é a correção mais rápida depois de encontrar a falha? Olhar como o backend acessa o banco e usar a solução nativa de parametrização da sua linguagem ou framework. Esse passo costuma cortar a injeção na raiz e não depende de infraestrutura.
- SQL Injection ainda é relevante em 2026? Sim. A falha continua aparecendo em sistemas novos sempre que o código monta consultas por concatenação, independentemente da linguagem ou do framework escolhido.
- Frameworks modernos como Drizzle ou Prisma protegem automaticamente? Eles oferecem caminhos parametrizados, mas exigem que você use a API da ferramenta. SQL bruto escrito manualmente pode reabrir a brecha, então vale verificar cada consulta crua do projeto.
- Qual a diferença entre privilégio mínimo e um WAF? O privilégio mínimo limita o que a aplicação pode executar no banco; o WAF filtra o tráfego que chega à aplicação. Um age depois da tentativa de injeção, o outro age antes de ela atingir o servidor.
Transforme o que você já explicou em texto
Neste artigo, a ideia central foi separar o que é dado do que é comando, e deixar cada camada com uma responsabilidade clara. Quem explica SQL Injection em uma aula ou vídeo costuma ter exatamente esse tipo de raciocínio organizado na cabeça, mas não no formato escrito.
Se você já gravou uma explicação sobre segurança, arquitetura ou qualquer tema técnico, o Skala Blog pega o link do vídeo, transcreve e gera uma versão em artigo pronta para revisão. Você cola a URL, revisa o texto e publica com a sua voz.
Fork this article
Start a new branch from the same video, shaped your way. You keep the credit; the original keeps the attribution.
A fork in another language is filed as a translation of this article, so the two pages point at each other. You can unlink it later from the editor.
0/240
You are creating
- Format
- For
- Language
- Source
- Your angle
You will be asked to sign in before it is generated.
Buy credits