Encontre o Sink de Injeção SQL: Identificando SQL Montado por Concatenação em Node.js

Segurança Web & API Nível 2/4 ~3 min 9 de julho de 2026

O desafio

Esta rota Node monta uma consulta SQL colando a entrada do usuário direto na string. Uma chamada executa esse SQL não filtrado contra o banco. Leia os dois arquivos e digite o nome dessa chamada.

O que você vai aprender

  • Reconhecer SQL construído por concatenação de string com entrada do usuário como um sink de injeção SQL
  • Rastrear um parâmetro de requisição desde o ponto de entrada até a chamada que o executa
  • Diferenciar uma query concatenada (db.query) de uma parametrizada (db.execute com placeholders)
  • Ler duas rotas semelhantes e identificar qual delas é explorável
  • Explicar por que parâmetros vinculados impedem a injeção

Habilidades testadas

Revisão de código-fonteReconhecimento de injeção SQLRastreamento de fluxo de dados

Pré-requisitos

  • Leitura básica de JavaScript
  • Familiaridade com parâmetros de query HTTP
  • Como é um SELECT SQL

Como funciona

Injeção SQL acontece quando entrada não confiável é misturada ao texto de uma instrução SQL em vez de ser enviada como dado. O parser do banco de dados não consegue distinguir qual parte da string era um valor e qual parte é um comando, então um atacante que controla o valor pode mudar o significado de toda a query.

Em users.js a rota lê req.query.id e monta a instrução com "SELECT ... WHERE id=" + id, e então a executa com db.query(sql). Um ?id=42 benigno funciona normalmente, e é por isso que o bug passa despercebido. Mas ?id=0 OR 1=1 faz a cláusula WHERE ser sempre verdadeira e despeja todos os usuários, e um payload UNION SELECT pode ler outras tabelas ou até credenciais. O valor nunca foi escapado, então é interpretado como SQL.

A correção está em orders.js. Ela usa um placeholder ? e passa o valor em um array separado: db.execute(sql, [req.query.user]). O driver vincula o valor como um parâmetro tipado, então ele nunca consegue escapar do seu lugar e virar SQL. Identificar o bug em uma revisão significa seguir o valor do usuário e perceber que ele acaba dentro da string da query, e não na lista de parâmetros.

Erros comuns

  • Culpar req.query.id. Ler a entrada não é o problema; a vulnerabilidade está em concatená-la no SQL e executá-la. Aponte a chamada que executa a query.
  • Escolher db.execute. Essa é a rota segura e parametrizada, ela vincula os valores, então não é o sink.
  • Assumir que um id inteiro é seguro. Nada valida que id é numérico; é uma string bruta vinda da URL.
  • Achar que um ORM ou framework escapa isso automaticamente. A concatenação bruta ignora qualquer proteção que o driver ofereça.

Como se proteger

Nunca construa SQL concatenando entrada do usuário. Sempre passe os valores como parâmetros vinculados para que o banco de dados os trate como dado, não como código.

  • Use queries parametrizadas ou prepared statements (db.execute(sql, [value])) para todo valor fornecido pelo usuário.
  • Valide e converta os tipos de entrada (por exemplo, transforme um id em número) antes que eles cheguem à camada de dados.
  • Aplique contas de banco de dados com privilégio mínimo para que uma query injetada não consiga ler tabelas não relacionadas.
  • Adicione uma regra de lint ou revisão de código que sinalize concatenação de string ao lado de db.query.

Solução completa

Membros Pro e Max desbloqueiam o passo a passo completo.

Assinar Pro

Estatísticas da comunidade

81 resoluções
70% taxa de sucesso
kevine Primeiro sangue

Hacks de hoje relacionados

25.000+ Hackers 100+ Labs & Cursos Grátis
Comece Grátis