AppSec & DevSecOps

Injeção de Dados em Banco: SQL Injection e NoSQLi Explicados para Desenvolvedores

Entenda como ocorrem as injeções em bancos relacionais (MySQL/PostgreSQL) e não-relacionais (MongoDB), por que a concatenação de strings é fatal e como as consultas parametrizadas resolvem o risco na raiz.

Laboratório de Engenharia de Segurança ByteAbyss
|
08 de Julho de 2026
|
14 min de leitura

Desde que o primeiro banco de dados relacional foi conectado à internet na década de 1990, uma vulnerabilidade tem se mantido de forma ininterrupta, persistente e desafiadora no topo absoluto do ranking canônico OWASP Top 10 (A03:2021 - Injection) e nas listas de riscos críticos mundiais da CWE/SANS: a Injeção de Banco de Dados (SQL Injection - SQLi e NoSQL Injection - NoSQLi).

Apesar de ser uma vulnerabilidade com mais de 25 anos de existência e cuja solução matemática já é perfeitamente conhecida pela ciência da computação, ela continua sendo o vetor de invasão primário responsável por vazamentos de dados catastróficos que expõem centenas de milhões de cartões de crédito, senhas corporativas e cadastros civis da LGPD em todo o mundo. O motivo da sua persistência é simples: a falha humana na escrita de código durante a comunicação entre a linguagem de backend (PHP, Node.js, Python, Java) e o motor do banco de dados.

Por Que a Injeção Acontece? O Erro da Concatenação Bruta

Para entender como um hacker explora um banco de dados, é preciso compreender uma limitação fundamental dos interpretadores SQL (seja MySQL, PostgreSQL, Oracle ou SQL Server): o motor do banco de dados é absolutamente incapaz de distinguir o que é a "instrução lógica de programação legítima programada pelo desenvolvedor" do que é a "string de dados enviada pelo usuário na tela" se ambos forem enviados misturados dentro de uma mesma frase de texto bruto.

Considere o seguinte exemplo de um código PHP clássico (e letalmente vulnerável) para uma tela de login corporativo:

// CÓDIGO VULNERÁVEL A SQL INJECTION (CONCATENAÇÃO BRUTA)
$email = $_POST['email'];
$senha = $_POST['senha'];

$sql = "SELECT * FROM usuarios WHERE email = '" . $email . "' AND senha = '" . $senha . "'";
$resultado = mysql_query($sql);

O programador desenhou essa consulta pressupondo que o usuário digitará no campo de e-mail um endereço comum como joao@empresa.com.br. O atacante, no entanto, digita no campo de e-mail do formulário a seguinte string sintática calculada: ' OR '1'='1' -- .

Quando o servidor PHP concatena essa string do hacker dentro da variável $sql e a envia ao motor MySQL, a instrução executada no servidor transforma-se matematicamente nesta frase:

SELECT * FROM usuarios WHERE email = '' OR '1'='1' -- ' AND senha = '...'

O que aconteceu no interpretador do banco de dados?

  1. O caractere de aspas simples (') digitado pelo hacker fechou prematuramente a string de busca do e-mail original (que ficou vazia '').
  2. O operador lógico OR foi introduzido seguido pela verdade tautológica universal ('1'='1'). Como 1 é sempre igual a 1 na matemática, a condição lógica WHERE do banco de dados passa a ser avaliada como TRUE (Verdadeira) para absolutamente todas as linhas existentes na tabela de usuários.
  3. A sequência de traços de comentário SQL (-- em MySQL/SQL Server ou #) instrui o motor do banco a ignorar, anular e descartar completamente o restante da consulta original — isto é, a checagem que exigia a verificação da senha foi deletada da execução!

O banco de dados obedece à consulta subvertida e retorna para a aplicação o primeiro registro de usuário da tabela — que em 99% dos portais corporativos corresponde exatamente à conta de Super Administrador / ID 1. O criminoso loga no painel administrativo sem nunca precisar adivinhar a senha da empresa.

As 4 Modalidades Ofensivas do SQL Injection

Nas auditorias de Pentest e caça a ameaças da ByteAbyss, nossos engenheiros classificam o SQL Injection em quatro variantes de exploração de acordo com o retorno exibido pelo servidor:

  • In-Band SQLi (UNION-Based): A modalidade de exfiltração em massa mais rápida. O atacante utiliza o operador relacional UNION SELECT para acoplar a consulta do formulário da web com buscas na tabela oculta information_schema. O hacker consegue despejar e extrair na própria tela do navegador (ou em arquivos JSON de resposta) 100% das tabelas do banco de dados da empresa, incluindo cartões de crédito, senhas com hash bcrypt e segredos da LGPD.
  • Error-Based SQLi: Ocorre quando o servidor web está configurado com exibição de erros de banco em modo verboso. O atacante força intencionalmente a geração de erros sintáticos (ex: tentando converter uma string em um inteiro) para que a mensagem de exceção devolvida pelo banco revele em seu texto a versão exata do software e nomes de tabelas (ex: Conversion failed when converting the varchar value 'admin_users' to data type int).
  • Blind SQL Injection (Injeção Cega - Boolean e Time-Based): A variante mais sofisticada, encontrada em sistemas seguros que não exibem erros na tela nem refletem dados no HTML. Como o hacker não enxerga a resposta na tela, ele descobre o banco de dados fazendo perguntas de "Sim ou Não" via scripts (como a ferramenta sqlmap) que monitoram o tempo de latência do servidor: ' OR IF(SUBSTRING(version(),1,1)='8', SLEEP(5), 0) -- . Se o site demorar exatamente 5 segundos para carregar no navegador, o script confirma cegamente que o banco rodando é a versão 8, extraindo todo o banco de dados letra por letra através de milissegundos de atraso na rede!
  • Out-of-Band (OOB) e Execução Remota de Código (RCE): A consagração mais destrutiva da invasão. Em servidores Microsoft SQL Server rodando como administrador de sistema (sa), o atacante aciona o procedimento nativo de execução de terminal xp_cmdshell via injeção: '; EXEC master..xp_cmdshell 'whoami' -- . Em bancos MySQL rodando com permissão root no Linux, o hacker usa a instrução INTO OUTFILE para escrever um arquivo de Web Shell em PHP (.php) diretamente na pasta pública do servidor web, tomando o controle computacional total da máquina host por RCE.

NoSQL Injection: O Mito da "Imunidade em Bancos Não-Relacionais"

Com a explosão do desenvolvimento em JavaScript (Node.js) e aplicações modernas na nuvem, muitos programadores adotaram bancos de dados orientados a documentos (NoSQL — como MongoDB, CouchDB, DynamoDB ou Redis) sob o falso mito de que "como não usam a linguagem SQL, são totalmente imunes a injeções". Essa premissa é um perigoso equívoco.

Em uma aplicação Node.js / Express construída com o driver Mongoose sobre o MongoDB, consultas de autenticação costumam ser modeladas recebendo objetos JSON do corpo da requisição:

// CÓDIGO NODE.JS / MONGODB VULNERÁVEL A NOSQL INJECTION
app.post('/login', async (req, res) => {
  const user = await User.findOne({
    username: req.body.username,
    password: req.body.password
  });
});

Se o programador não validar se os campos req.body.username e password são estritamente strings de texto simples, um atacante pode interceptar a requisição HTTP POST no Burp Suite e enviar no corpo em formato JSON não um texto, mas um objeto contendo operadores lógicos nativos de consulta do MongoDB, como o operador de negação $ne (Not Equal / Diferente de) ou $gt (Greater Than / Maior que):

// PAYLOAD MALICIOSO ENVIADO PELO ATACANTE NO JSON POST:
{
  "username": "admin",
  "password": { "$ne": null }
}

O que acontece dentro do motor do MongoDB? A instrução é compilada como: "Encontre o usuário cujo username seja 'admin' e cuja senha seja qualquer valor diferente de nulo (null)". Como a senha real do administrador no banco de dados obviamente não é nula (ela é um hash válido), a condição lógica de negação é avaliada como TRUE (Verdadeira)! O atacante burla a autenticação do MongoDB instantaneamente e loga como admin sem saber a senha.

A Prevenção Definitiva: Consultas Parametrizadas (Prepared Statements)

A única estratégia técnica 100% infalível, cientificamente comprovada e inegociável para erradicar o SQL Injection de qualquer sistema de software é substituir todas as concatenações de strings pelo uso universal de Consultas Parametrizadas (Parameterized Queries) com Instruções Preparadas (Prepared Statements) no driver do banco de dados (como o PDO em PHP ou JDBC em Java).

// CÓDIGO PHP SEGURO E BLINDADO COM PDO PREPARED STATEMENTS
$stmt = $pdo->prepare("SELECT * FROM usuarios WHERE email = :email AND senha = :senha");
$stmt->execute([
  'email' => $_POST['email'],
  'senha' => $_POST['senha']
]);
$usuario = $stmt->fetch();

Por que o Prepared Statement com PDO é imune a injeções? Porque a comunicação de rede entre o servidor PHP e o servidor MySQL acontece em duas etapas de protocolo estritamente separadas:

  1. Etapa 1 (Compilação da Estrutura Lógica): O PHP envia primeiro para o banco de dados apenas o "esqueleto" lógico da consulta com os marcadores em branco (:email e :senha). O motor MySQL compila, analisa e trava a estrutura lógica de execução na memória do servidor.
  2. Etapa 2 (Envio de Dados Binários Isolados): Em um pacote de rede completamente separado, o PHP envia os dados digitados pelo usuário. Como a estrutura lógica da consulta já foi compilada e engessada na etapa 1, o banco de dados trata qualquer coisa enviada na etapa 2 (mesmo que o usuário digite o terrível ' OR '1'='1' ; DROP TABLE usuarios; --) estrita e incondicionalmente como um bloco literal de texto inofensivo que será buscado na coluna de e-mail. É matematicamente impossível ao caractere de aspas subverter a consulta para executar um comando.

Quer Garantir Que Suas Aplicações e Bancos de Dados Estão Imunes?

Nossos auditores de AppSec realizam análises estáticas de código (SAST) e Pentests Gray Box profundos para identificar e sanar qualquer consulta SQL ou NoSQL insegura antes do deploy.

Auditar Segurança de Bancos de Dados com a ByteAbyss
Autoridade de Conteúdo

Laboratório de Engenharia de Segurança ByteAbyss

Pesquisadores de Vulnerabilidades (OWASP Top 10 / CWE)

Voltar ao Blog
Compartilhar:

Continue Lendo no Blog da ByteAbyss

Defesa Cibernética & SOC 12 min de leitura
Como Funciona um Ataque de Ransomware de Extorsão Tríplice (e Como Blindar Sua Empresa)

Os cartéis de Ransomware como LockBit e BlackCat abandonaram a simples criptografia de discos. Descubra como funciona a extorsão tríplice com exfiltração de dados e como a imutabilidade WORM, EDR comportamental e Pentest contínuo formam a blindagem corporativa definitiva.

Ler Artigo Completo
AppSec & DevSecOps 15 min de leitura
O Guia Definitivo de DevSecOps: Como Integrar SAST, DAST e SCA em Pipelines CI/CD

Aprenda a implementar o Shift-Left Security na esteira do GitHub Actions, GitLab CI e Azure DevOps. Veja na prática como configurar varredura de segredos, SAST estático, SCA de dependências open source e testes DAST interativos.

Ler Artigo Completo
Segurança Ofensiva & Red Team 10 min de leitura
Pentest Black Box vs Gray Box vs White Box: Qual a Melhor Abordagem para Sua Empresa?

Caixa Preta, Cinza ou Branca? Cada modalidade de Pentest possui objetivos estratégicos distintos, custos operacionais e níveis de visibilidade técnica. Veja como escolher o teste certo para cada momento do seu negócio.

Ler Artigo Completo
Proteção Avançada

A superfície pública é apenas o primeiro passo

Scans passivos revelam exposições externas lógicas óbvias. Proteja sua infraestrutura de ponta a ponta contratando os especialistas em cibersegurança da **ByteAbyss** para executar auditorias profundas.