A injeção de SQL (SQLi) é a vulnerabilidade web mais icônica da história — décadas depois de descoberta, ainda causa vazamentos massivos. Ela permite ao atacante manipular as consultas que a aplicação faz ao banco de dados, podendo ler dados que não deveria (bancos inteiros de usuários e senhas), burlar autenticação, e às vezes até executar comandos no servidor. Fiel ao princípio do curso, você vai aprendê-la na mão primeiro — entendendo por que funciona — antes de tocar em ferramentas automatizadas. Isso é o que separa quem entende SQLi de quem só roda o SQLmap. Pratique no DVWA, que tem SQLi em vários níveis.

Onde a consulta é montada

Primeiro, o mecanismo. Aplicações web guardam dados em bancos SQL e os consultam com comandos SQL. O problema nasce quando a aplicação constrói a consulta misturando comando e entrada do usuário sem separá-los. Imagine um login que verifica as credenciais assim (de forma insegura):

SELECT * FROM usuarios WHERE usuario = 'ENTRADA_USUARIO' AND senha = 'ENTRADA_SENHA'

A aplicação insere o que você digitou nos lugares de ENTRADA_USUARIO e ENTRADA_SENHA. Se ela faz isso "colando" sua entrada diretamente na string do comando, você pode quebrar a estrutura da consulta injetando SQL na sua entrada. Este é o cerne: sua entrada, que deveria ser dado, é interpretada como comando — a definição de injeção (aula OWASP Top 10: o mapa das vulnerabilidades web).

O bypass de autenticação, passo a passo

O exemplo clássico de bypass de autenticação ilustra o poder. No campo de usuário, você digita:

admin' --

A consulta vira: SELECT * FROM usuarios WHERE usuario = 'admin' --' AND senha = '...'. O ' fecha a string do usuário, e o -- (comentário em SQL) faz o banco ignorar todo o resto da consulta — inclusive a verificação de senha. Resultado: você loga como admin sem saber a senha. Ou o clássico ' OR '1'='1 no campo de senha, que torna a condição sempre verdadeira. Entender por que esses payloads funcionam — porque quebram e reescrevem a lógica da consulta — é o objetivo desta aula, e é o que permite adaptá-los a situações que nenhuma lista prevê.

Extrair dados com UNION

A partir do bypass, a SQLi escala para extração de dados, e a técnica principal é o UNION-based. O operador SQL UNION combina os resultados de duas consultas — então, se você injeta um UNION SELECT, pode fazer a aplicação retornar dados de outras tabelas junto com (ou no lugar de) os resultados esperados. O processo, conceitualmente: você descobre quantas colunas a consulta original retorna (com tentativas como ORDER BY), descobre quais colunas são exibidas na página, e então usa UNION SELECT para trazer dados que quiser — nomes de tabelas, colunas, e por fim o conteúdo (usuários, senhas/hashes). Bancos guardam informação sobre sua própria estrutura (o information_schema), que você consulta via SQLi para mapear o banco e saber o que extrair. É um processo metódico: descobrir a estrutura, depois saquear os dados.

Blind SQL Injection: quando a página nada revela

Nem toda SQLi mostra os dados diretamente na página, e aí entra a categoria mais sutil: a Blind SQL Injection (injeção cega). Às vezes a aplicação é vulnerável mas não exibe o resultado da consulta — então você não vê os dados. Você os infere por canais indiretos. Na boolean-based, você faz perguntas de sim/não ao banco ("a primeira letra da senha do admin é 'a'?") e observa se a página responde diferente para verdadeiro vs. falso, extraindo os dados um caractere por vez. Na time-based, você faz o banco esperar (com um comando de delay) se a condição for verdadeira, e mede o tempo de resposta — se demorou, a resposta foi "sim". É lento e trabalhoso na mão — daí a automação fazer sentido —, mas entender o conceito — extrair dados por inferência a partir de diferenças de comportamento — é essencial, e é a mesma lógica de "ler a resposta" da arquitetura web e HTTP.

A raiz: código e dado no mesmo lugar

O ponto conceitual central da SQLi, que vale para toda injeção: a falha é misturar código (o comando SQL) com dados (a entrada do usuário) sem separá-los. Quando a fronteira entre "isto é instrução" e "isto é dado fornecido" se apaga, o dado pode virar instrução. Essa é a essência da injeção em qualquer contexto (SQL, comandos, LDAP, etc.), e entendê-la aqui te prepara para reconhecê-la em toda parte. É por isso que fazer SQLi na mão é tão formador: você vê a fronteira se quebrar.

A defesa é conhecida, robusta e definitiva

Do lado defensivo, a SQLi tem uma solução conhecida, robusta e definitiva — o que torna sua persistência ainda mais frustrante. A defesa principal são as prepared statements (consultas parametrizadas): em vez de colar a entrada na string da consulta, o código separa o comando SQL dos dados, enviando-os ao banco por canais distintos, de modo que a entrada do usuário nunca é interpretada como comando — ela é sempre tratada como dado, ponto final. Isso elimina a SQLi na raiz, tornando impossível quebrar a estrutura da consulta. Complementarmente: validação de entrada (rejeitar o que não faz sentido), menor privilégio no banco (a conta que a aplicação usa não deve poder ler tudo nem executar comandos de sistema, limitando o dano de uma SQLi), ORMs usados corretamente (que parametrizam por padrão), e WAFs (que filtram payloads conhecidos, uma camada adicional, não a solução). A lição: a SQLi é totalmente prevenível com prepared statements, e sua persistência se deve a código legado e desenvolvimento inseguro, não à falta de solução — eco do EternalBlue.

Fontes e leituras recomendadas

Exercícios

  1. Qual é a causa raiz da SQL Injection em termos de como a consulta é construída?

    ✓ Resposta:

    A causa raiz é a aplicação construir a consulta SQL misturando o comando com a entrada do usuário sem separá-los — "colando" a entrada diretamente na string do comando. Assim, a entrada, que deveria ser dado, pode ser interpretada como parte do comando.

  2. Explique por que o payload admin' -- no campo de usuário burla a autenticação.

    ✓ Resposta:

    Porque o ' fecha a string do nome de usuário na consulta e o -- inicia um comentário SQL, fazendo o banco ignorar todo o restante da consulta, inclusive a verificação de senha (AND senha = '...'). O resultado é autenticar como admin sem fornecer a senha.

  3. O que é uma UNION-based SQLi e como ela permite extrair dados de outras tabelas?

    ✓ Resposta:

    É uma SQLi que usa o operador UNION SELECT para combinar os resultados da consulta original com os de outra consulta escolhida pelo atacante, retornando dados de outras tabelas. Descobre-se o número de colunas e quais são exibidas, e então se usa o UNION para trazer estruturas (via information_schema) e conteúdos desejados.

  4. O que diferencia a Blind SQL Injection, e como as variantes boolean-based e time-based extraem dados sem vê-los?

    ✓ Resposta:

    A Blind SQLi ocorre quando a aplicação é vulnerável mas não exibe o resultado da consulta, exigindo inferência. Na boolean-based, faz-se perguntas de sim/não e observa-se se a página responde diferente para verdadeiro vs. falso, extraindo dado a dado. Na time-based, faz-se o banco esperar (delay) se a condição for verdadeira, e mede-se o tempo de resposta para inferir a resposta.

  5. Qual é a defesa principal e definitiva contra SQLi, e por que ela elimina a falha na raiz?

    ✓ Resposta:

    A defesa principal são as prepared statements (consultas parametrizadas), que separam o comando SQL dos dados, enviando-os ao banco por canais distintos. Isso elimina a falha na raiz porque a entrada do usuário nunca é interpretada como comando — é sempre tratada como dado, tornando impossível quebrar a estrutura da consulta.