SQL injection é um ataque onde código SQL malicioso é inserido em campos de entrada de aplicações para manipular ou extrair dados de um banco de dados sem autorização.
TL;DR SQL injection (SQLi) é um ataque de injeção de código no qual um atacante insere instruções SQL maliciosas em campos de entrada que são repassados a uma query de banco de dados. Quando a aplicação não sanitiza a entrada, o banco de dados executa os comandos do atacante em vez da query pretendida. SQL injection é a vulnerabilidade #1 no OWASP Top 10 e pode resultar em comprometimento total do banco de dados, exfiltração de dados, bypass de autenticação e, em alguns casos, execução remota de código. A prevenção requer queries parametrizadas (prepared statements) — não apenas filtragem de entrada.
O que é SQL injection?
SQL injection (SQLi) é uma técnica de ataque na qual um atacante insere ou “injeta” código SQL malicioso em uma query que uma aplicação envia ao seu banco de dados. Quando a aplicação concatena entrada de usuário não validada diretamente em uma query SQL, o banco de dados interpreta a entrada do atacante como comandos SQL e os executa.
SQL injection não requer a exploração de uma vulnerabilidade de software no sentido tradicional — ele explora a falha em separar código de dados. Qualquer aplicação que constrói queries SQL usando concatenação de strings a partir de entrada fornecida pelo usuário é potencialmente vulnerável.
SQL injection está presente na lista OWASP Top 10 de riscos críticos de segurança em aplicações web desde que a lista foi publicada pela primeira vez em 2003. De acordo com o OWASP Top 10 de 2021, falhas de injeção (incluindo SQLi) ocupam o #3, afetando 94% das aplicações testadas.
Como o SQL injection funciona
Considere um formulário de login que constrói esta query:
SELECT * FROM users WHERE username = '$username' AND password = '$password';Um usuário normal envia maria e senha123. A query se torna:
SELECT * FROM users WHERE username = 'maria' AND password = 'senha123';Um atacante envia ' OR '1'='1 como nome de usuário. A query se torna:
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = 'qualquer_coisa';Como '1'='1' é sempre verdadeiro, a query retorna todos os usuários — e o atacante está logado como o primeiro usuário no banco de dados, geralmente um administrador.
Tipos de SQL injection
SQL injection in-band
O atacante usa o mesmo canal para injetar o ataque e recuperar os resultados. É o tipo mais comum.
| Subtipo | Como funciona |
|---|---|
| Baseado em erros | Força o banco de dados a retornar mensagens de erro contendo dados (ex.: nomes de tabelas, valores de colunas) |
| Baseado em UNION | Usa UNION SELECT para anexar uma segunda query e retornar seus resultados junto com os originais |
SQL injection inferencial (blind)
| Subtipo | Como funciona |
|---|---|
| Baseado em booleano | Envia queries que avaliam como verdadeiro ou falso; infere dados a partir das diferentes respostas |
| Baseado em tempo | Usa SLEEP() ou WAITFOR DELAY; infere dados a partir do tempo de resposta |
SQL injection out-of-band
O atacante faz o banco de dados enviar dados para um servidor externo (via requisições DNS ou HTTP). Este tipo é menos comum e depende de funcionalidades específicas do banco de dados — como procedimentos armazenados que realizam chamadas de rede. É frequentemente utilizado quando os canais in-band são lentos ou instáveis.
O que SQL injection pode causar
| Impacto | Descrição |
|---|---|
| Bypass de autenticação | Fazer login sem credenciais válidas |
| Exfiltração de dados | Ler qualquer tabela a que o usuário do banco de dados tenha acesso |
| Modificação de dados | Executar INSERT, UPDATE ou DELETE em registros |
| Descoberta de esquema | Enumerar tabelas, colunas e a estrutura do banco de dados |
| Escalada de privilégios | Explorar procedimentos armazenados para obter privilégios de DBA |
| Execução remota de código | Em alguns bancos de dados (ex.: MSSQL com xp_cmdshell), executar comandos do sistema operacional |
Como prevenir SQL injection
1. Use queries parametrizadas (prepared statements)
Queries parametrizadas são a defesa primária e mais eficaz contra SQL injection. Ao separar o código SQL dos dados do usuário, elas eliminam a possibilidade de a entrada ser interpretada como SQL.
Vulnerável:
query = "SELECT * FROM users WHERE username = '" + username + "'"Seguro:
query = "SELECT * FROM users WHERE username = ?"cursor.execute(query, (username,))O mesmo princípio se aplica em outras linguagens:
// Java com PreparedStatementPreparedStatement stmt = conn.prepareStatement( "SELECT * FROM users WHERE username = ?");stmt.setString(1, username);ResultSet rs = stmt.executeQuery();// Node.js com mysql2const [rows] = await connection.execute( 'SELECT * FROM users WHERE username = ?', [username]);2. Use um ORM
ORMs (Django ORM, Hibernate, ActiveRecord, Sequelize) constroem queries parametrizadas por padrão, reduzindo o risco de SQL injection ao abstrair a construção manual de queries. No entanto, ainda é possível introduzir vulnerabilidades ao usar queries SQL brutas dentro de um ORM — sempre prefira a API de query do ORM.
3. Aplique o princípio do menor privilégio
A conta de banco de dados usada pela aplicação deve ter apenas as permissões que precisa. Se a aplicação apenas lê dados, o usuário do banco de dados não deve ter permissões de DELETE ou DROP. Isso não previne SQL injection, mas limita o impacto caso um ataque seja bem-sucedido.
4. Implante um Web Application Firewall (WAF)
Um WAF detecta e bloqueia padrões de SQL injection em requisições HTTP antes que elas cheguem à aplicação. Um WAF de qualidade analisa parâmetros de URL, cabeçalhos HTTP, cookies e o corpo da requisição em busca de payloads SQLi conhecidos. No entanto, um WAF é uma camada de defesa em profundidade — nunca uma substituição para queries parametrizadas no código da aplicação.
5. Valide e sanitize a entrada
Valide tipo, comprimento e formato das entradas. Por exemplo, se um campo espera um inteiro, rejeite qualquer valor que não seja numérico. Essa abordagem reduz a superfície de ataque, mas não é suficiente por si só — atacantes podem contornar validações de entrada, especialmente em campos de texto livre.
6. Use listas de permissão em vez de listas de negação
Quando possível, valide a entrada em relação a um conjunto conhecido de valores válidos (lista de permissão) em vez de tentar bloquear padrões maliciosos (lista de negação). Por exemplo, se um parâmetro orderby aceita apenas name ou date, rejeite qualquer outro valor.
Detecção de SQL injection
Sinais de que uma aplicação pode ser vulnerável:
- Mensagens de erro contendo sintaxe SQL (ex.:
You have an error in your SQL syntax) - Respostas diferentes ao acrescentar
' OR '1'='1versus' OR '1'='2 - Atrasos de tempo ao injetar
SLEEP(5)ouWAITFOR DELAY '00:00:05' - Erros HTTP 500 inesperados ao enviar aspas simples (
') ou duplas (") em campos de entrada - Diferenças no comportamento da aplicação ao modificar parâmetros de URL com caracteres SQL especiais
Ferramentas automatizadas como sqlmap são amplamente usadas por pesquisadores de segurança e atacantes para detectar e explorar vulnerabilidades de SQL injection. Testes de penetração regulares e revisões de código são fundamentais para identificar SQLi antes que os atacantes o façam.
SQL injection e o OWASP Top 10
O OWASP (Open Web Application Security Project) mantém uma lista das dez categorias de vulnerabilidades de segurança mais críticas em aplicações web. Falhas de injeção — incluindo SQL injection — aparecem nessa lista desde sua primeira publicação em 2003.
| Edição OWASP | Ranking de injeção |
|---|---|
| OWASP Top 10 2013 | #1 |
| OWASP Top 10 2017 | #1 |
| OWASP Top 10 2021 | #3 (presente em 94% das aplicações) |
A consolidação no ranking 2021 reflete uma reorganização das categorias, não uma redução da ameaça. SQL injection continua sendo uma das vulnerabilidades mais exploradas em ambientes de produção.
Perguntas frequentes
O que é SQL injection em termos simples? SQL injection é quando um atacante engana um site para executar comandos de banco de dados que não eram intencionados. Se um formulário de login passa a entrada do usuário diretamente para uma query de banco de dados sem verificá-la, um atacante pode digitar comandos SQL em vez de um nome de usuário real e manipular o banco de dados.
SQL injection ainda é uma ameaça em 2026? Sim. SQL injection tem sido a vulnerabilidade de aplicação web mais crítica por mais de duas décadas. Apesar de ser bem compreendida, persiste porque desenvolvedores continuam construindo queries usando concatenação de strings, especialmente em código legado e em projetos com baixa maturidade de segurança.
O que é uma query parametrizada? Uma query parametrizada é uma instrução SQL onde a entrada do usuário é passada como um parâmetro separado, não concatenada na string da query. O banco de dados trata a entrada como dados — nunca como código SQL. Isso elimina fundamentalmente o vetor de SQL injection.
Um WAF sozinho consegue parar SQL injection? Um WAF bloqueia padrões conhecidos de SQL injection e fornece uma importante camada de defesa em profundidade, mas não pode ser a única proteção. A correção fundamental é sempre queries parametrizadas no código da aplicação. Atacantes avançados podem contornar regras de WAF usando variações de payload, codificação ou fragmentação.
Quais bancos de dados são afetados por SQL injection? Todos os bancos de dados relacionais que processam SQL: MySQL, PostgreSQL, Microsoft SQL Server, Oracle, SQLite. A sintaxe SQL específica varia por banco de dados — por exemplo, SLEEP() no MySQL versus WAITFOR DELAY no MSSQL — mas a vulnerabilidade subjacente é a mesma.
Qual é a diferença entre SQL injection e XSS? SQL injection tem como alvo a camada de banco de dados — o atacante envia SQL malicioso para ser executado pelo banco de dados. XSS tem como alvo os usuários — o atacante injeta JavaScript malicioso que é executado nos navegadores de outros usuários. Ambos exploram falhas de validação de entrada, mas em camadas diferentes da aplicação.
Como funciona o SQL injection blind? No SQL injection blind (cego), a aplicação não retorna dados do banco de dados em sua resposta. O atacante infere informações observando diferenças no comportamento (baseado em booleano — por exemplo, a página carrega de forma diferente para true versus false) ou no tempo de resposta (baseado em tempo — o servidor demora mais para responder quando um SLEEP() é injetado com sucesso).
Qual é o ranking do OWASP para SQL injection? Injeção (incluindo SQL injection) ocupa o #3 no OWASP Top 10 2021, presente em 94% das aplicações testadas. Em edições anteriores (2013, 2017), injeção ocupava o #1. A mudança de ranking reflete uma reorganização das categorias, não uma diminuição da prevalência ou gravidade.