Quase toda vulnerabilidade segue o mesmo esqueleto:
ENTRADA ──▶ PROCESSAMENTO ──▶ SAÍDA / AÇÃO
(dado do (o servidor faz (resultado:
atacante) algo com o dado) vaza dado, executa código,
muda estado…)
A falha nasce quando o processamento confia na entrada. Veja os quatro tipos mais comuns por essa lente — repare que é sempre a mesma história:
- Injeção (SQLi, comando): a entrada do atacante é misturada com um comando (uma consulta ao banco, por ex.) e o servidor executa como se fosse instrução, não dado. "
nome = ' OR 1=1 --" engana a consulta e vaza a tabela inteira. - XSS (Cross-Site Scripting): a entrada do atacante é devolvida na página e o navegador de outra vítima executa como JavaScript. No projeto isso acontece de forma indireta: um título malicioso entra pela API pública → é lido → mandado para a IA → a IA repete → a tela do admin renderiza como HTML cru (
dangerouslySetInnerHTML) → o script roda no navegador do admin (Ex. 33). Cadeia longa, mesma causa raiz: confiou na saída da IA. - Autorização quebrada (IDOR/BOLA): a entrada é um identificador (ex.:
?id=123) e o servidor entrega o objeto sem checar se aquele usuário podia vê-lo. Troca123por124e vê o dado de outro. - SSRF (Server-Side Request Forgery): a entrada é uma URL e o servidor busca essa URL sem validar — o atacante o faz buscar endereços internos (ex.:
169.254.169.254, que na nuvem entrega credenciais). (Ex. 44)
Se você internalizar "a falha está em confiar na entrada/saída", você vai prever vulnerabilidades em vez de decorá-las. Essa é a diferença entre executar um exercício e compreender — que é o seu objetivo.
A correção também tem um padrão
- Validar/sanitizar a entrada (aceitar só o formato esperado; recusar o resto).
- Separar dado de instrução (consultas parametrizadas, nunca concatenar; renderizar como texto, nunca como HTML).
- Verificar autorização em toda ação sensível (não só autenticação).
- Menor privilégio (cada peça só acessa o mínimo).
- Defesa em profundidade (mais de uma camada).