FlawOpen

flawopen.com/Cross-Site Scripting

Cross-Site Scripting

Alta CWE-79
Idioma: English Português (Brasil) Español Français Deutsch Русский 简体中文 日本語 हिन्दी 한국어 Bahasa Indonesia

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 href e src. 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-src baseado em nonce e sem 'unsafe-inline' bloqueia a maioria dos scripts injetados mesmo quando um erro de codificação escapa, e require-trusted-types-for 'script' tranca os sinks do DOM.

Fluxo de Ataque Passo a Paso

Passo 1

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.

Passo 2

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.

Passo 3

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.

Passo 4

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

Python JavaScript Go Java PHP C# Ruby C/C++ Rust Kotlin Swift

Lista de Verificação de Segurança para Engenharia

Leitura relacionada

XSS refletido, armazenado e de DOM explicados Escapar basta? CSP ou escape? O DOMPurify basta? XSS pela renderização de Markdown