XSS for frontend devs: from input to exploit

How an innocent text field can compromise an entire application. Vulnerable code, attack, and step-by-step fix.

O que é XSS?

Cross-Site Scripting (XSS) acontece quando um atacante consegue injetar e executar JavaScript arbitrário no contexto do navegador de outra pessoa. É o tipo de vulnerabilidade que todo dev frontend deveria conhecer — porque ela vive exatamente no código que você escreve todo dia.

O código vulnerável

Esse padrão aparece mais do que parece:

// ❌ vulnerável
const name = new URLSearchParams(location.search).get('name');
document.getElementById('greeting').innerHTML = `Olá, ${name}!`;

Se alguém acessar /page?name=<img src=x onerror=alert(document.cookie)>, o script executa. O atacante agora tem acesso aos cookies da vítima.

Como o ataque funciona

  1. O atacante cria uma URL com payload injetado
  2. Envia o link para a vítima (phishing, fórum, email)
  3. A vítima abre o link — o script roda no contexto dela
  4. O atacante pode roubar cookies, tokens de sessão, ou fazer requisições autenticadas

XSS é particularmente perigoso em aplicações que usam localStorage para guardar JWTs — o token inteiro pode ser exfiltrado em uma linha de JavaScript.

A correção

// ✅ seguro — textContent nunca interpreta HTML
const name = new URLSearchParams(location.search).get('name');
document.getElementById('greeting').textContent = `Olá, ${name}!`;

Se você realmente precisar de HTML dinâmico, use uma biblioteca de sanitização:

import DOMPurify from 'dompurify';

const clean = DOMPurify.sanitize(userInput);
element.innerHTML = clean;

Como testar

Abra o DevTools, vá para a URL vulnerável e teste payloads simples:

?name=<script>alert(1)</script>
?name=<img src=x onerror=alert(1)>
?name=<svg onload=alert(1)>

Se qualquer um desses fizer aparecer um alert, você tem XSS.

Ferramentas

  • Burp Suite — intercepta requisições e injeta payloads automaticamente
  • DOMPurify — sanitização client-side confiável
  • CSP (Content Security Policy) — camada de defesa extra via header HTTP