
Repositório de PoC para CVE-2025-68147: Cross-Site Scripting (XSS) Armazenado no OpenSourcePOS. A vulnerabilidade permite escalonamento de privilégios por meio de injeção de JavaScript malicioso no módulo Store Config. Inclui detalhes do payload e verificação do patch (v3.4.0). Pesquisador de Segurança: Aditya Singh (Nixon-H).
| Metadados | Detalhes |
|---|---|
| ID do CVE | CVE-2025-68147 |
| Severidade | Alta CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:H/I:H/A:N |
| Tipo de Vulnerabilidade | Cross-Site Scripting Armazenado (CWE-79) |
| Versões Afetadas | OpenSourcePOS v3.4.0, v3.4.1 |
| Versão Corrigida | v3.4.2 |
| Componente Vulnerável | Módulo de Configuração da Loja (campo Política de Devolução) |
| Relator | Aditya Singh (Nixon-H) |
Uma vulnerabilidade de Cross-Site Scripting (XSS) Armazenado foi descoberta no módulo de Configuração da Loja do OpenSourcePOS. O aplicativo não sanitizou adequadamente a entrada fornecida pelo usuário no campo "Política de Devolução" antes de armazená-la na tabela de banco de dados ospos_app_config.
Essa falha permitiu que um atacante autenticado com privilégios de configuração (ou um atacante que explorasse uma cadeia CSRF separada) injetasse payloads JavaScript arbitrários. Como a "Política de Devolução" é renderizada dinamicamente em todos os recibos de venda, o payload injetado é executado automaticamente no navegador de qualquer usuário — incluindo caixas com privilégios baixos, outros administradores ou clientes — sempre que um recibo é gerado ou visualizado.
A vulnerabilidade reside no template de visualização do recibo: app/Views/sales/receipt_default.php.
O aplicativo recupera a string "Política de Devolução" do array de configuração global ($this->config['return_policy']) e a prepara para exibição.
nl2br() para converter quebras de linha em quebras de linha HTML (<br>).nl2br() não sanitiza caracteres especiais de HTML. Ela deixa tags como <script>, `` e atributos onload completamente intactos.Código Vulnerável (Antes do Patch):
<div id="sale_return_policy">
<?php echo nl2br($this->config['return_policy']); ?>
</div>
Quando um administrador salva a configuração, o payload é armazenado bruto no banco de dados.
ospos_app_configreturn_policyPolicy Text... <script>alert('XSS')</script>Como não há sanitização de entrada no lado do controlador (Config.php) nem escape de saída no lado da visão (receipt_default.php), o aplicativo está vulnerável a XSS Armazenado.
O ataque tem como alvo o painel de Configuração da Loja, mas impacta o módulo Vendas/Recibo.
http://[TARGET]/config (solicitação POST para salvar a configuração)http://[TARGET]/sales/receipt/[SALE_ID]Passo 1: A Injeção Entramos como Administrador e navegamos até Configuração da Loja -> Geral. Na área de texto "Política de Devolução", injetamos o seguinte payload específico:
Standard Return Policy: No Refunds.
<script>alert('XSS_BY_NIXON_SUCCESSFUL')</script>
Passo 2: Persistência
Ao clicar em "Enviar", o aplicativo enviou uma solicitação POST para /config/save. O payload foi confirmado com sucesso no banco de dados.
Passo 3: O Gatilho Para verificar o impacto em outros usuários:
http://localhost/sales/receipt/1). O navegador analisa a div return_policy, encontra a tag <script> e executa imediatamente o JavaScript.Resultado Observado:
Uma caixa de alerta do navegador apareceu com a mensagem: XSS_BY_NIXON_SUCCESSFUL.
Captura de Tela 1: O Alerta Disparado
Captura de Tela 2: Payload na Configuração
🎥 Demonstração em Vídeo: Clique para Baixar / Assistir ao Vídeo do PoC
Esta é uma vulnerabilidade de Escopo Alterado (S:C) porque o ataque é armazenado no servidor, mas é executado no contexto do navegador da vítima.
/sales/receipt/105). O script é executado silenciosamente, enviando document.cookie (contendo o ID de ospos_session) para o servidor do atacante./employees/save.hacker / password123) é criada instantaneamente em segundo plano. A vítima não vê nada além do recibo, enquanto o atacante ganha uma porta dos fundos permanente.A vulnerabilidade foi corrigida no OpenSourcePOS v3.4.2.
O mantenedor aplicou um patch que implementa Codificação de Saída Sensível ao Contexto. O valor de configuração agora é envolvido pela função auxiliar global esc() do CodeIgniter antes de ser passado para nl2br().
O Patch (Commit 22297a):
<div id="sale_return_policy">
<?php echo nl2br(esc($this->config['return_policy'])); ?>
</div>
Verificação: Após atualizar para a v3.4.2, o mesmo payload é renderizado como texto inofensivo:
Standard Return Policy: No Refunds. <script>alert('XSS_BY_NIXON_SUCCESSFUL')</script>
22297a) e verificado pelo pesquisador.