Prevenção de XSS: codificação de saída e CSP
Compreender XSS refletido, armazenado e baseado no DOM, escapar a saída controlada pelo utilizador, evitar innerHTML com dados não confiáveis e adicionar um cabeçalho de Política de Segurança de Conteúdo.
Prevenção de XSS: codificação de saída e CSP é uma aula grátis de Frontend Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Frontend Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Frontend Academy inclui 4 aulas no total.
O que é XSS?
Execução de scripts entre sites acontece quando um invasor injeta JavaScript executável na sua página. O navegador o executa com os privilégios da sua origem, permitindo roubar cookies, sequestrar sessões, alterar a aparência da página e redirecionar o usuário para malware.
Três tipos de XSS
Armazenado: o script malicioso é salvo no banco de dados e enviado a todos os visitantes. Refletido: a entrada é devolvida na resposta (?q=<script>...). Baseado em DOM: o JS do cliente grava dados não confiáveis no DOM.
A causa principal: innerHTML com dados não confiáveis
Usar innerHTML (ou v-html, dangerouslySetInnerHTML) com strings controladas pelo usuário é o principal vetor de XSS.
// BAD: user input rendered as HTML
el.innerHTML = userComment; // attacker submits <img onerror=alert(1)>
// Vue equivalent:
<div v-html="userComment"></div> // same bug
// React equivalent:
<div dangerouslySetInnerHTML={{ __html: userComment }} /> // same bugCodificação da saída (o padrão seguro)
Trate strings não confiáveis como texto, não como HTML. React, Vue, Angular e Svelte fazem isso por padrão na interpolação {value}.
// SAFE: text content, not HTML
el.textContent = userComment; // <script> shows as literal text
// React (auto-escaped):
<div>{userComment}</div>
// Vue (auto-escaped):
<div>{{ userComment }}</div>Sanitização quando for necessário renderizar HTML
Se você realmente precisar renderizar HTML fornecido pelo usuário (como em editores de texto rico), faça a sanitização com DOMPurify; nunca crie seu próprio sanitizador baseado em expressões regulares.
import DOMPurify from 'dompurify';
const clean = DOMPurify.sanitize(userHtml);
el.innerHTML = clean; // strips <script>, on* handlers, dangerous URLsValidação de URLs
URLs controladas pelo usuário em href ou src podem acionar XSS por meio de esquemas javascript:.
// BAD:
<a href={userUrl}>Click</a>
// attacker submits: javascript:alert(1)
// GOOD: whitelist protocols:
function safeUrl(url) {
if (!/^https?:\/\//.test(url) && !url.startsWith('/')) return '#';
return url;
}Política de Segurança de Conteúdo (CSP)
CSP é um cabeçalho de resposta HTTP que informa ao navegador quais fontes de scripts, estilos, imagens e outros recursos são permitidas. Mesmo que um invasor injete um script, o navegador se recusa a executá-lo.
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.trusted.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:CSP estrita com nonce
Para scripts incorporados que você controla, use um nonce por solicitação. Os scripts injetados pelo invasor não terão o nonce correspondente.
// Server generates a random nonce per request:
const nonce = crypto.randomBytes(16).toString('base64');
res.setHeader('Content-Security-Policy', `script-src 'nonce-${nonce}' 'strict-dynamic'`);
// Inject into the HTML:
<script nonce="abc123">/* trusted inline code */</script>Cookies HttpOnly + Secure
Defina os cookies de sessão com HttpOnly para impedir que JavaScript os leia; mesmo que ocorra XSS, o invasor não poderá obter o token da sessão.
Set-Cookie: session=abc; HttpOnly; Secure; SameSite=StrictIntegridade de subrecursos (SRI)
Ao carregar scripts de terceiros por meio de um CDN, use SRI para verificar se o conteúdo corresponde a um hash. Um CDN comprometido não pode fornecer um script malicioso sem invalidar a verificação do hash.
<script
src="https://cdn.example.com/lib.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous"
></script>Tipos Confiáveis (Experimental)
Tipos Confiáveis são um recurso do navegador (baseado em Chromium) que força destinos perigosos (innerHTML) a receber um objeto de Tipo Confiável — impedindo completamente a inserção de cadeias de caracteres.
Testes de XSS
Tente injetar <img src=x onerror=alert(1)> em todas as entradas de texto que são renderizadas novamente. Se um alerta for exibido, há um erro de XSS. Use ferramentas como OWASP ZAP para realizar varreduras automatizadas.
Verificação rápida
Por que {userInput} do React é seguro por padrão, mas dangerouslySetInnerHTML não é?
Recapitulação: prevenção de XSS
Opte por renderizar texto por padrão (a sintaxe {x} do React e {{ x }} do Vue é segura). Faça a higienização com DOMPurify ao renderizar HTML. Coloque os protocolos de URL em uma lista de permissões. O cabeçalho CSP (com nonces ou 'strict-dynamic') bloqueia scripts injetados. Cookies HttpOnly impedem o roubo por JS. Use o hash SRI nos scripts de CDN. Teste as entradas com cargas úteis clássicas.
Perguntas Frequentes
A aula “Prevenção de XSS: codificação de saída e CSP” é grátis?
Sim — o texto completo de “Prevenção de XSS: codificação de saída e CSP” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Frontend Academy, atualize para CoddyKit PRO. O curso de Frontend Academy inclui 4 aulas no total.
O que vou aprender em “Prevenção de XSS: codificação de saída e CSP”?
Compreender XSS refletido, armazenado e baseado no DOM, escapar a saída controlada pelo utilizador, evitar innerHTML com dados não confiáveis e adicionar um cabeçalho de Política de Segurança de Cont… Você pratica Frontend Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Frontend Academy?
Nenhuma experiência prévia é necessária. Frontend Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.
Quanto tempo leva a aula “Prevenção de XSS: codificação de saída e CSP”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Frontend Academy?
Sim. Cada aula de Frontend Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Prevenção de XSS: codificação de saída e CSP
- CSRF: cookies SameSite e tokens
- Política de Segurança de Conteúdo: nonce e hash
- Fluxos OAuth no frontend