Vulnerabilidade de XSS persistente em endpoint de criação/edição de uma conversa
Descrição do Problema
Foi identificada uma vulnerabilidade Cross-Site Scripting (XSS) do tipo Persistente (Stored XSS), especificamente nos campos "Text to be displayed as welcome" e "Text to be presented at the end of the collection" durante a criação e/ou edição de conversas.
Essa falha permite que um atacante insira código JavaScript malicioso que é armazenado no banco de dados e posteriormente executado no navegador de qualquer usuário que acesse a conversa.
Contexto e Impacto
-
Tipo de vulnerabilidade: XSS Persistente (Stored XSS)
-
Localização:
-
conversation-welcome.jinja2— linha 48 -
card.jinja2— linha 18
-
-
Causa raiz:
- Falta de sanitização no backend.
- Uso do filtro
|safeno Jinja2, que impede o escaping de HTML.
Essa falha viola o princípio de Defesa em Profundidade (Defense in Depth) e permite a execução de código arbitrário sob o domínio da aplicação.
Prova de Conceito (PoC)
Passos para reprodução:
-
Autentique-se como um usuário com permissão para criar conversas.
-
Obtenha o cookie de sessão e os tokens CSRF da aplicação (via DevTools).
-
Envie uma requisição
POSTdireta ao endpoint:/boards/{username}/conversations/add/ou
/boards/{username}/conversations/{id}/{slug}/edit/ -
No campo
welcome_message, insira o payload malicioso:<script>alert('XSS Reproduzido!');</script> -
Acesse a URL da conversa criada:
/boards/{username}/conversations/{id}/{slug}/welcome/ -
Observe a execução automática do script no navegador.
Resultado esperado: O alerta é exibido, comprovando a execução do código injetado e a persistência da vulnerabilidade.
Extra: A descrição dessa issue é limitada, a apesar de indicar totalmente o problema encontrado. Logo, se forem necessárias mais informações sobre a execução da vulnerabilidade em PoC, com imagens e ferramentas, pode-se acessar o documento em PDF no OneDrive: Relatório-XSS-V1_0-EJ.pdf
Causa Técnica
- Falta de sanitização no backend antes do armazenamento no banco de dados.
- Confiança indevida na sanitização realizada pelo frontend.
- Uso do filtro
|safeno Jinja2, que permite renderização direta de HTML sem escaping.
Recomendação / Proposta de Mitigação
Implementar sanitização obrigatória no backend para todo conteúdo Rich Text antes de salvar no banco de dados.
Ações sugeridas:
-
Usar biblioteca de sanitização: Para Python/Django, recomenda-se a biblioteca
nh3. -
Configurar allow-list restrita:
- Permitir apenas tags HTML seguras (
<b>,<i>,<p>,<a>, etc.) - Remover atributos perigosos (
onclick,onerror,javascript:).
- Permitir apenas tags HTML seguras (
-
Aplicar sanitização nos endpoints vulneráveis:
/boards/{username}/conversations/add/ /boards/{username}/conversations/{id}/{slug}/edit/ -
Evitar o uso direto de
|safeno Jinja2 para dados dinâmicos sem validação.
Severidade e Risco
| Categoria | Nível |
|---|---|
| Impacto | Alto — execução arbitrária de código no cliente |
| Probabilidade de exploração | Baixa |
| Exploração requer autenticação | Sim |
| Tipo | Stored XSS |