Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
Outils/GitHubGitHub/squeeze440/zotlit-poc
Analyse des VulnérabilitésExploitationExfiltration de DonnéesCollecte d'InformationsVirtualisation de SécuritéArticles et Recherche
GitHubsqueeze440/zotlit-poc

zotlit-PoC

PoC — l'import de pièces jointes copie des fichiers depuis des chemins locaux non approuvés dans ZotLit (GHSA-4qh7-66xv-h329, CVE-2026-87000, CVSS 5.5).

Voir le dépôt
20il y a 19 joursPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

ZotLit : avis de sécurité

Statut CVE : demandé, en attente d'attribution. Cette découverte est publiée sous GHSA-4qh7-66xv-h329. À l'attribution de la CVE, ce dépôt est renommé CVE-YYYY-NNNNN-zotlit-PoC et cette bannière est remplacée par le lien CVE.

ChercheurDostxodjayev Abdullox (@squeeze440)
AvisGHSA-4qh7-66xv-h329
CVSS 3.15.5 (Moyen)
FaiblesseCWE-73, CWE-200

Résumé

Le contrôle externe du nom de fichier ou du chemin dans la fonctionnalité d'import de pièces jointes d'AidenLx ZotLit (aidenlx/zotlit) 1.1.12 permet à un attaquant qui contrôle une bibliothèque Zotero partagée/synchronisée de divulguer des fichiers locaux arbitraires du système de fichiers de la victime dans le coffre Obsidian de la victime via un chemin de pièce jointe linked_file forgé.

Produit

ZotLit — plugin Obsidian pour l'intégration Zotero (aidenlx/zotlit, id du plugin zotlit, version du manifeste 1.1.12)

Version testée

Commit Git 41e60aaa6178629b34f8a42d104e757594b72435 (2026-07-31)

CVSS v3.1 estimé

CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N — 5.5 (Moyen)

Métriques non évidentes : AV:L — l'exploitation se produit lorsque le processus local Obsidian/zotlit de la victime traite des métadonnées d'élément Zotero fournies par l'attaquant (livrées via une bibliothèque partagée/synchronisée), la même convention utilisée pour les bugs de type « fichier malveillant traité par une application locale », même si la livraison elle-même peut se faire par le réseau (bibliothèque de groupe partagée, fichier d'export envoyé par e-mail). UI:R — la victime doit importer/synchroniser la bibliothèque malveillante dans Zotero et exécuter la fonctionnalité d'import de notes de ZotLit (ou l'intégration d'annotations/citations) sur une note référençant la pièce jointe forgée ; il s'agit d'un usage courant de la fonctionnalité centrale du plugin, activée par défaut (attachment.import vaut true par défaut), et non d'une action inhabituelle. I:N/A:N — cette découverte n'est qu'une primitive de lecture/copie ; aucune traversée de chemin côté destination n'est revendiquée (voir Détails pour une observation connexe mais non vérifiée).

Détails

ZotLit lit les métadonnées des pièces jointes directement depuis la base SQLite de Zotero (ou une bibliothèque synchronisée/partagée), y compris la colonne en texte libre itemAttachments.path, et lui fait entièrement confiance pour résoudre l'emplacement depuis lequel lire une pièce jointe « liée » :

  • packages/db/src/lib/zt-path.ts:62-63 — attachmentAbsPath(), cas "linked-absolute" :

    case "linked-absolute":
      return parsed.path;
    

    Pour les lignes linkMode: 2 (linked_file) dont le path ne porte pas le placeholder de répertoire de base attachments:, parsed.path est la chaîne brute de la base de données renvoyée telle quelle comme chemin absolu du système de fichiers à lire — aucune liste blanche, aucune confinement au répertoire de données Zotero ou à tout emplacement approuvé par l'utilisateur.

  • packages/db/src/lib/context/zt-template-attach.ts:101-106 — attachmentFilename(), cas "linked-absolute" :

    case "linked-absolute":
      return basename(path.path);
    

    Le nom de fichier utilisé pour construire la copie dans le coffre est dérivé de ce même chemin contrôlé par l'attaquant via basename(), de sorte que le nom de fichier de destination est influencé par l'attaquant mais sans séparateur de chemin (sûr contre la traversée sur cette branche).

  • apps/obsidian/src/services/note-import/note-parser.ts:403-430 — resolveEmbeddedImage() est invoqué lors de la conversion d'une annotation d'image intégrée d'une note de littérature Zotero en Markdown Obsidian (une action courante et par défaut de la fonctionnalité « Import Note » de ZotLit). Il résout sourcePath = attachmentAbsPath(attachment, ...) et appelle deps.resolveLink({ sourcePath, vaultName: \${attachment.key}-${filename}` })` — mettant en file d'attente une copie de n'importe quel chemin absolu choisi par l'attaquant vers le coffre.

  • apps/obsidian/src/services/attachment-import/service.ts:125-155 — AttachmentImportBatch.resolveLink() met en file d'attente { source: sourcePath, dest: <dossier de pièces jointes du coffre>/<key>-<filename> }, conditionné uniquement par le paramètre attachment.import, dont la valeur par défaut est true (apps/obsidian/src/services/settings/schema.ts:123).

  • apps/obsidian/src/lib/copy-attachments.ts:43-60 — copyAttachment() effectue la lecture+écriture réelle sans aucune validation de chemin : stat(source) puis copyFile(source, dest).

Effet net : un attaquant capable de faire entrer un élément Zotero linked_file (linkMode 2) dans la bibliothèque de la victime — par exemple une bibliothèque de groupe Zotero partagée, un export .rdf/.json/Better BibTeX que la victime importe, ou une bibliothèque synchronisée sur laquelle l'attaquant a un accès en écriture — peut définir le chemin de pièce jointe de cet élément vers n'importe quel fichier du disque de la victime (~/.ssh/id_rsa, stockages d'identifiants de navigateur, autres coffres, fichiers .env, etc.). Dès que la victime exécute l'import de notes de ZotLit (ou affiche/intègre cette annotation) avec le paramètre par défaut attachment.import: true, ZotLit copie silencieusement le contenu de ce fichier dans le coffre Obsidian de la victime sous un nom prévisible (<attachmentKey>-<basename>). Comme les coffres sont couramment synchronisés, commités dans git ou publiés, cela déplace des données que l'attaquant n'aurait jamais pu atteindre autrement vers un emplacement que l'attaquant (ou toute autre personne ayant accès à la cible de synchronisation) peut lire.

Observation connexe non vérifiée (ne fait pas partie du PoC de cette découverte) : la branche sœur "storage" de attachmentFilename() (zt-template-attach.ts:103-104) renvoie le suffixe de chemin brut sans l'appel basename() appliqué aux deux autres branches. La question de savoir si cela est exploitable de manière indépendante dépend de la façon dont le mécanisme de synchronisation de stockage de Zotero nomme les fichiers téléchargés localement, ce qui est hors de ce dépôt et n'a pas été vérifié — signalé ici uniquement comme une lacune de durcissement qu'il vaut la peine de combler par cohérence.

Preuve de concept

Vérification dynamique : les fonctions vulnérables exactes (parseAttachmentPath, attachmentAbsPath, attachmentFilename, copyAttachments/copyAttachment/writeCopy/destMatches, isErrno, reflink) ont été extraites verbatim (fichier:ligne cités ci-dessus, logique inchangée) depuis le code source livré et exécutées directement dans Node, car une installation complète hors ligne de l'espace de travail pnpm n'était pas disponible dans ce bac à sable (chaîne d'outils corepack/pnpm cassée hors ligne). La seule substitution a été de remplacer l'appel au logger LogTape par console.warn — purement cosmétique, aucun effet sur le flux de contrôle. Script : ~/engagements/zotlit/evidence/poc-verify.mjs.

Télécharger l’outil