Como escolher um scanner de injeção SQL

Yuta Matsuyama

Pesquisador de segurança, TECHFUND Inc.

Atualizado:

Para quem é: Equipes de desenvolvimento e segurança escolhendo ferramentas de teste de injeção SQL.

Resposta prática

Para investigar injeção de SQL, primeiro defina se o que você quer examinar é uma aplicação Web em execução ou o código-fonte. Para a primeira opção, use testes dinâmicos com ferramentas como ZAP e sqlmap; para a segunda, use análise de código. Na prática, vale verificar os pontos importantes com as duas abordagens.

Antes de escolher um scanner, defina o ponto de partida da verificação

Imagine, por exemplo, que o valor digitado em um formulário de busca seja incorporado diretamente a uma instrução SQL. Os testes dinâmicos enviam requisições reais e procuram problemas com base em diferenças nas respostas, entre outros sinais. A análise de código rastreia por onde o valor entra e para quais consultas ele é enviado.

Os testes dinâmicos não conseguem examinar telas ou APIs que não possam alcançar. A análise de código também pode deixar passar problemas, dependendo das linguagens e dos frameworks compatíveis e da configuração do escopo da análise. Mesmo que uma das abordagens não encontre nenhum problema, não se pode concluir que a outra se tornou desnecessária.

Ferramentas representativas e quando usar cada uma

ZAP: é uma opção de código aberto para quem quer verificar uma aplicação Web como um todo. Tem regras de varredura ativa para injeção de SQL e permite investigar também outras vulnerabilidades Web. No entanto, ZAP Baseline realiza varredura passiva por padrão; portanto, apenas executá-lo não significa que os testes ativos de injeção de SQL foram concluídos.

sqlmap: é uma ferramenta de código aberto para quando há suspeita sobre um ponto de entrada específico e se deseja concentrar a verificação em injeção de SQL. Além da detecção, oferece recursos de automação da exploração, por isso deve ser usada com um escopo autorizado definido e em um ambiente no qual seja possível limitar os impactos.

Burp Suite Professional: destina-se a profissionais que desejam combinar o scanner com verificações manuais enquanto examinam requisições HTTP. O scanner automático está incluído em edições pagas, como Professional, mas não na Community Edition gratuita.

Wapiti: é uma ferramenta de código aberto que examina aplicações Web como caixa-preta pela linha de comando. A documentação oficial descreve testes de injeção de SQL baseados em erros, valores booleanos e diferenças de tempo, além de varreduras de APIs usando arquivos OpenAPI. Verifique caso a caso se a ferramenta consegue alcançar os caminhos necessários em alvos que incluam SPAs ou autenticação complexa.

Todas essas ferramentas enviam requisições para aplicações em execução. Registre, junto com os resultados, até onde elas conseguiram chegar, considerando não apenas as telas, mas também as APIs acessíveis após a autenticação, as interfaces administrativas e as permissões de cada usuário. Combine essas ferramentas com a análise estática do código-fonte como uma opção distinta.

Ao adotar uma ferramenta, compare tanto o número de detecções quanto o alcance

No mesmo ambiente de homologação, prepare entradas com problemas conhecidos e entradas parametrizadas de forma segura para fazer a comparação. Além de verificar se a ferramenta encontra as primeiras, confira se ela não classifica erroneamente as segundas como problemáticas. Verifique também se a autenticação não expirou e interrompeu os testes no meio do caminho, e se foi possível percorrer todos os pontos de entrada necessários, incluindo APIs que usam JSON.

As varreduras podem afetar os dados de teste ou a disponibilidade. Obtenha autorização explícita do proprietário do alvo e acorde o escopo, o horário de execução, a carga e as operações a excluir. Se possível, faça os testes em um ambiente separado da produção.

O caso MOVEit mostra a importância de verificar também os caminhos públicos

No registro da NVD sobre a CVE-2023-34362 do MOVEit Transfer, uma injeção de SQL poderia permitir que um invasor não autenticado acessasse o banco de dados. O registro também menciona sua exploração entre maio e junho de 2023. Durante o desenvolvimento, é necessário verificar não apenas o processamento após o login, mas também os caminhos públicos. O exemplo abaixo é um material didático fictício em TypeScript e node-postgres; não representa a implementação do MOVEit nem é um código de reprodução dessa CVE. Limite os testes a alvos autorizados.

Depois de encontrar o problema, separe os valores da estrutura SQL

A base da correção é passar os valores externos como parâmetros, em vez de concatená-los à string SQL. No entanto, elementos da própria estrutura SQL, como a ordenação e os nomes de tabelas, nem sempre podem ser tratados apenas com a vinculação de valores a parâmetros. Nesses casos, escolha entre opções fixas definidas pela aplicação.

No próximo exemplo, o valor da busca é vinculado a um parâmetro, e a ordenação é escolhida entre duas consultas fixas. Além disso, limite os privilégios do usuário do banco de dados ao mínimo necessário e verifique separadamente se o usuário da aplicação tem permissão para visualizar esses dados. Após a correção, repita os testes para confirmar que o problema apontado foi resolvido e que a busca normal continua funcionando.

Exemplo didático de node-postgres no lado do servidor. O valor é vinculado a $1, o ORDER BY é escolhido entre duas consultas fixas e ordenações desconhecidas são rejeitadas. A autorização dos usuários e a limitação dos privilégios do banco de dados ao mínimo necessário devem ser tratadas separadamente. Verifique também se as aspas são tratadas como dados, se ambas as ordenações funcionam e se o acesso de usuários sem permissão é negado.
import type { Pool } from "pg";

export async function findProducts(
  db: Pool, name: string, sort: string,
) {
  const queries = {
    newest: "SELECT id, name FROM products WHERE name = $1 ORDER BY created_at DESC, id DESC LIMIT 50",
    oldest: "SELECT id, name FROM products WHERE name = $1 ORDER BY created_at ASC, id ASC LIMIT 50",
  } as const;
  if (sort !== "newest" && sort !== "oldest") {
    throw new Error("Invalid sort");
  }
  return db.query(queries[sort], [name]);
}
Exemplo: separar o valor de busca da estrutura SQL
  1. O usuário insere um valor de busca
  2. A aplicação vincula o valor a $1
  3. A aplicação envia uma consulta fixa e o valor ao banco de dados

Escolha estruturas SQL, como ORDER BY, entre consultas fixas permitidas. Autorização e privilégios mínimos no banco são requisitos separados; este diagrama não garante segurança.

Perguntas frequentes

Um scanner garante que não há injeção SQL?

Não. Cobertura, configuração e acesso de teste limitam o que pode ser encontrado. Combine testes com revisão de código.

Posso testar uma aplicação em produção?

Somente com autorização explícita e escopo acordado. Testes dinâmicos podem afetar dados ou disponibilidade; use um ambiente controlado sempre que possível.

Fontes e leituras

Como o Hi AUDIT Agent pode ajudar

Com o Hi AUDIT Agent, revise fluxos de dados, locais identificados e sugestões de correção no código. Confirme a cobertura de injeção SQL para seu ambiente e peça a uma pessoa que valide o resultado.

Criar uma conta no Hi AUDIT Agent