Glossário
O que é injeção de SQL (SQLi) — quando a entrada reescreve os comandos do seu banco de dados
Injeção de SQL (SQLi) é quando a entrada do usuário reescreve o significado de uma consulta ao banco, levando a ler, alterar ou apagar dados. Como funciona e a defesa real: placeholders / prepared statements, ORMs e privilégio mínimo no banco.
"O texto que você digitou em uma caixa de busca vira 'parte de um comando' para o banco de dados" — isso é injeção de SQL. Veja como funciona e como evitá-la de forma confiável (sem passos de ataque).
Por que acontece (o mecanismo)
A causa raiz é montar SQL por concatenação de strings. Misture a entrada direto na instrução e ela pode cruzar a "fronteira de valor" e agir como comando.
✗ Concatenação de strings (perigosa)
Entrada concatenada na instrução → a entrada pode ser lida como parte do comando
✓ Placeholders (segura)
Valores passados para slots ? / $1 como dado → sempre permanecem valores
O dano é "tudo o que aquela conexão de banco pode fazer". Se o banco interno é alcançável, é uma entrada clássica para vazamentos em massa, ao lado de RCE e SSRF.
Defesa
Use placeholders / prepared statements (o mais importante)
Não monte SQL por concatenação. Passe os valores via ? / parâmetros nomeados como 'dado'. Só isso quase elimina toda a classe.
Apoie-se no seu ORM / query builder
A maioria dos ORMs usa placeholders por padrão. Quanto menos SQL cru você escrever à mão, mais seguro. Se você precisar escrever SQL cru, sempre parametrize-o.
Usuário de banco com privilégio mínimo
Não conceda ao usuário de banco da aplicação direitos desnecessários (DROP, outras tabelas, operações de admin). Mesmo se comprometido, contenha o dano.
Validação de entrada como complemento
Checagens de tipo/comprimento/formato ajudam, mas não as torne sua defesa principal — elas ficam por cima dos placeholders.
A visão deste site: pare de montar SQL cru à mão, para começar
A SQLi existe desde sempre e ainda não morre — porque é "conveniente" misturar a entrada na instrução. A posição deste site é clara: nunca crie um lugar onde valores sejam concatenados em SQL. Faça dos placeholders ou de um ORM o padrão e essa vulnerabilidade desaparece por design. Não siga o caminho de "se esforçar mais no escape manual".
Um ponto cego: placeholders só carregam 'valores'
Placeholders não são uma cura para tudo. Eles carregam apenas valores — não a estrutura da consulta, como nomes de tabela, nomes de coluna ou a direção do ORDER BY (asc/desc).
Quando você precisa que isso seja dinâmico (por exemplo, deixar o usuário escolher uma "chave de ordenação" ou "coluna de filtro"), não jogue a entrada no SQL — em vez disso, selecione o nome real de uma allowlist predefinida. "Coluna de ordenação" e "coluna de filtro" são os pontos cegos clássicos onde as pessoas assumem que os placeholders as cobrem.
Leia a seguir
- Glossário: O que é RCE · O que é XSS
- Fundamentos: Fundamentos de segurança
FAQ
QO que acontece com a injeção de SQL?
Um invasor muda o significado de uma consulta ao banco de dados — lendo dados que deveriam estar ocultos, alterando-os ou, na pior das hipóteses, apagando tudo ou contornando a autenticação. É uma causa clássica de vazamentos massivos de dados.
QQual é a defesa mais confiável?
Passar valores via placeholders (prepared statements). Não monte SQL com concatenação de strings; passe os valores como 'dado' por um canal separado, para que a entrada nunca possa ser lida como comando. A maioria dos ORMs faz isso por padrão.
QEscapar a entrada é suficiente?
O escape manual é propenso a erros e desencorajado. Use placeholders. Dê também ao usuário do banco privilégio mínimo para reduzir o raio de impacto caso algo passe.