flawopen.com/Cross-Site Scripting
Cross-Site Scripting
O cross-site scripting acontece quando uma página inclui texto de um usuário de um jeito que o navegador interpreta como HTML ou JavaScript, e esse texto roda para outros usuários com a autoridade do próprio site. A correção é a mesma em todo lugar: codificar cada valor para o ponto exato onde é escrito, sanitizar os raros campos que precisam aceitar HTML e reforçar os dois com uma Content Security Policy. Escolha sua linguagem abaixo para ver as APIs exatas, o código vulnerável e o corrigido e as regras de CI que detectam o problema.
Explicação em Linguagem Simples (ELI5)
Um jornal publica cartas de leitores nas próprias páginas. Um leitor escreve uma carta diagramada exatamente como um aviso do editor: 'Assinantes: liguem para este número e informem os dados do cartão para renovar.' Impressa na fonte do próprio jornal, os leitores confiam nela como se o editor a tivesse escrito. XSS é um site imprimindo o texto de um visitante na própria página, onde o navegador confia nele como código do próprio site, com o acesso do site à sua conta. Escapar é imprimir cada carta dentro de um quadro de citação bem marcado, para que nenhuma se passe por aviso do editor.
Conceitos Centrais e Termos
- Cross-site scripting (CWE-79)
- Uma página web inclui dados não confiáveis sem neutralizá-los para o navegador, então marcação ou script nesses dados é interpretado e executado na origem da página, com acesso ao DOM, aos cookies e às APIs.
- Reflected, stored and DOM-based XSS
- O XSS refletido devolve dados da requisição direto na resposta, em geral por um link preparado. O XSS armazenado salva o valor e o serve a todo visitante. O XSS baseado em DOM nem passa pelo servidor: o JavaScript do cliente copia dados da URL ou do armazenamento para um sink como
innerHTML. - Contextual output encoding
- Cada contexto de saída precisa da sua própria codificação: entidades HTML para texto de elemento e atributos entre aspas, escape de string JavaScript dentro de scripts, percent-encoding em parâmetros de URL e verificação de esquema em
hrefesrc. Codificar como HTML um valor posto dentro de um script não basta. - Sanitizing vs encoding
- Codificar mostra a marcação como texto. Quando usuários precisam enviar formatação, passe o HTML por um sanitizador de allowlist (DOMPurify, nh3, o sucessor do bleach, OWASP Java HTML Sanitizer, HtmlSanitizer, ammonia) que mantém as tags permitidas e remove scripts, manipuladores de eventos e URLs
javascript:. - Content Security Policy (CSP)
- Um cabeçalho de resposta que diz ao navegador quais scripts podem rodar. Um
script-srcbaseado em nonce e sem'unsafe-inline'bloqueia a maioria dos scripts injetados mesmo quando um erro de codificação escapa, erequire-trusted-types-for 'script'tranca os sinks do DOM.
Fluxo de Ataque Passo a Paso
Texto não confiável chega a uma página
Um termo de busca, campo de perfil, comentário, fragmento de URL ou resposta de API é incluído quando a página é montada no servidor ou atualizada no navegador.
Ele é escrito sem a codificação certa
O escape do template é desligado, o valor vai para um contexto de script ou URL que o escape HTML não cobre, ou o código do cliente o atribui a innerHTML. O valor de teste inofensivo <img src=x onerror=alert(1)> sobrevive intacto.
O navegador o interpreta como código
O navegador da vítima monta um elemento <img> real e dispara onerror, ou executa um link javascript: quando clicado.
O script age como o site
Ele roda com a origem do site: pode ler a página, chamar as APIs do site com os cookies ou tokens da vítima, mudar o que o usuário vê e enviar formulários em nome dela.
Guias de XSS por linguagem
Lista de Verificação de Segurança para Engenharia
- Renderize toda página com um template engine com escape automático ligado e revise cada exceção (
|safe,Html.Raw,dangerouslySetInnerHTML,raw,unsafe { },{!! !!}). - Codifique para o contexto exato: texto HTML e atributos entre aspas, strings JavaScript, parâmetros de URL; nunca monte HTML ou JavaScript por concatenação de strings.
- Sanitize HTML enviado por usuários com um sanitizador de allowlist mantido, no ponto em que ele é renderizado.
- Aceite apenas
httpehttpsem URLs fornecidas por usuários antes que cheguem ahref,srcou navegação. - Envie uma Content-Security-Policy baseada em nonce, sem
'unsafe-inline', além deX-Content-Type-Options: nosniff. - Guarde tokens de sessão em cookies
HttpOnly,SecureeSameSite=Lax, e não nolocalStorage.