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é.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
obsidian-note-toolbar-PoC — PoC — exécution arbitraire de JavaScript pilotée par le frontmatter dans Note Toolbar pour Obsidian (GHSA-q8cw-3m8c-5pf2, CVE-2026-87002, CVSS 7.0). | Kitploit
Outils/GitHubGitHub/squeeze440/obsidian-note-toolbar-poc
Analyse StatiqueAnalyse des VulnérabilitésAnalyse de CodeExploitationExploitation d'Applications WebArticles et RechercheApprentissage et ÉducationDéveloppement de Charges Utiles
GitHub
squeeze440/obsidian-note-toolbar-poc

obsidian-note-toolbar-PoC

PoC — exécution arbitraire de JavaScript pilotée par le frontmatter dans Note Toolbar pour Obsidian (GHSA-q8cw-3m8c-5pf2, CVE-2026-87002, CVSS 7.0).

Voir le dépôt
30il y a 1 moisPas 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

Exécution de code arbitraire pilotée par le frontmatter dans Note Toolbar via la chaîne de variables {{prop_NAME}} → {{js:}}

Statut CVE : demandé, en attente d'attribution. Cette découverte est publiée sous GHSA-q8cw-3m8c-5pf2. À l'attribution du CVE, ce dépôt sera renommé CVE-YYYY-NNNNN-obsidian-note-toolbar-PoC et cette bannière sera remplacée par le lien CVE.

ChercheurDostxodjayev Abdullox (@squeeze440)
AvisGHSA-q8cw-3m8c-5pf2
CVSS 3.17.0 (Élevé)
FaiblesseCWE-94, CWE-1336

Exécution de code arbitraire pilotée par le frontmatter dans Note Toolbar via la chaîne de variables {{prop_NAME}} → {{js:}}

Résumé

Une neutralisation incorrecte de la sortie dans le moteur de substitution de variables de Note Toolbar (plugin Obsidian) permet à un attaquant qui contrôle le frontmatter YAML d'une note (par exemple un collaborateur sur un coffre synchronisé/partagé) d'obtenir une exécution de code arbitraire sur la machine de la victime lorsque celle-ci ouvre simplement la note, en injectant une charge utile {{js: ...}} dans une propriété du frontmatter qu'un élément de barre d'outils préexistant, non-script, référence via {{prop_NAME}} dans son libellé/infobulle/lien.

Produit

Note Toolbar (note-toolbar) — plugin communautaire Obsidian Dépôt : https://github.com/chrisgurney/obsidian-note-toolbar

Version testée

v1.34.12 (commit 520271c3027eb6da38bab10a686b21e14c664c13, 2026-07-29), contre Obsidian desktop 1.13.4 sous Linux.

CVSS v3.1 estimé

7.0 (Élevé) — CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H

  • AV:L — le composant vulnérable (l'évaluateur JS du plugin, s'exécutant dans le renderer Electron d'Obsidian) n'est pas exposé au réseau ; la charge utile arrive sous forme de contenu local de coffre/fichier synchronisé par tout moyen utilisé par la victime (Git, Syncthing, Obsidian Sync, dossier partagé), ce qui est cohérent avec les découvertes antérieures de cette famille (par ex. obsidian-syncthing-integration, obsidian-codescript-toolkit).
  • AC:H — l'exploitation dépend de conditions hors du contrôle de l'attaquant qui doivent déjà exister sur l'installation de la victime : (1) le réglage « Scripting » du plugin doit déjà être activé (désactivé par défaut), et (2) la victime doit déjà avoir configuré un élément de barre d'outils dont le libellé, l'infobulle ou le lien est une référence nue {{prop_NAME}} vers une clé de frontmatter. Les deux sont des schémas d'utilisation réalistes et documentés, mais aucun n'est la configuration par défaut.
  • PR:N — l'attaquant n'a besoin d'aucun accès au système de la victime, seulement de la capacité de faire entrer une note dans le coffre de la victime avec un frontmatter contrôlé par l'attaquant.
  • UI:R — la victime doit ouvrir/visualiser la note spécifique ; aucun clic sur l'élément de barre d'outils n'est nécessaire, la barre d'outils se rend automatiquement.
  • S:U, C:H/I:H/A:H — le code s'exécute avec un accès Node.js complet (require('child_process'), système de fichiers, etc.) en tant que compte utilisateur local exécutant Obsidian.

Détails

Note Toolbar prend en charge une variable documentée {{prop_NAME}} qui substitue la valeur du frontmatter d'une note dans le libellé, l'infobulle ou le lien d'un élément de barre d'outils (skills/note-toolbar-variables/SKILL.md, wiki Variables.md). Il prend également en charge une variable {{js: <expr>}} qui évalue l'expression comme du JavaScript vivant lorsque le réglage « Scripting » du plugin est activé.

Le bug réside dans l'ordre des opérations dans src/Toolbar/VariableResolver.ts::replaceVars() :

  1. Lignes 74–92 : les espaces réservés {{prop_KEY}} sont substitués par la valeur brute de frontmatter[KEY] de la note courante — inconditionnellement, indépendamment du réglage scriptingEnabled, et indépendamment de la source de cette valeur de frontmatter.
  2. Lignes 94–104 (à l'intérieur de if (this.ntb.settings.scriptingEnabled)) : la fonction vérifie ensuite s.trim().startsWith('{{js:') sur la chaîne déjà substituée s, et si c'est vrai, retire l'enveloppe {{js:/}} et passe le reste à JavaScriptAdapter.use() pour évaluation.

Parce que l'étape 1 s'exécute avant l'étape 2 et réécrit s sur place, une valeur de frontmatter qui commence elle-même par {{js: et se termine par }} est promue de « texte affiché » à « script exécuté » — même si l'élément de barre d'outils n'a jamais été conçu comme un élément script. Le propriétaire de l'élément de barre d'outils n'a jamais tapé que {{prop_status}} ; la charge utile exécutable provient entièrement du frontmatter de la note elle-même.

JavaScriptAdapter.evaluate() (src/Adapters/JavaScriptAdapter.ts:143-205) exécute l'expression avec un véritable AsyncFunction non sandboxé :

src/Adapters/Adapter.ts:11
protected static readonly AsyncFunction = (Object.getPrototypeOf(async function(){}) as { constructor: typeof Function }).constructor;

src/Adapters/JavaScriptAdapter.ts:164
const func = new JavaScriptAdapter.AsyncFunction("input", expression);
...
result = await Promise.resolve((func as (...args: unknown[]) => unknown)(args));

Il s'agit du véritable constructeur AsyncFunction du moteur JS, et non d'un interpréteur/sandbox — à l'intérieur du renderer Electron d'Obsidian, il dispose d'un accès complet à require()/Node.js, confirmé dans le PoC ci-dessous via require('child_process').execSync(...).

Point crucial : l'adaptateur JS est intégré et ne nécessite aucun plugin compagnon (src/Adapters/AdapterManager.ts:59 : adapter = this.js; // built-in, doesn't rely on plugin), contrairement aux préfixes de variables Dataview/Templater/JS-Engine qui nécessitent l'installation de ces plugins. Seul le propre commutateur « Scripting » du plugin (scriptingEnabled, par défaut false, src/Settings/NoteToolbarSettings.ts:300) le conditionne.

Enfin, le chemin de rendu qui déclenche la substitution est automatique, non conditionné à un clic : ToolbarRenderer.ts::renderLItems() appelle this.ntb.vars.resolveText(toolbar, file) (src/Toolbar/ToolbarRenderer.ts:418) à chaque rendu d'une barre d'outils pour une note — c'est-à-dire à l'ouverture/visualisation de la note — ce qui résout le libellé et l'infobulle de chaque élément via replaceVars(). Aucun clic sur l'élément de barre d'outils affecté n'est nécessaire.

L'affectation barre d'outils-vers-note est elle-même pilotée par le frontmatter (réglage toolbarProp, clé par défaut notetoolbar, src/Settings/NoteToolbarSettings.ts:317), de sorte qu'une note synchronisée peut sélectionner la barre d'outils qui s'y affiche — mais cela n'est pas nécessaire à l'exploitation si la victime utilise déjà une barre d'outils par défaut ou un mappage de dossier incluant l'élément vulnérable.

Ceci est distinct du risque documenté par le SECURITY.md du mainteneur lui-même (« User scripts... executes JavaScript provided by the user... intentional and by design ») — cela décrit un utilisateur qui conçoit sciemment un élément de barre d'outils {{js:}}, ou qui importe sciemment une configuration de barre d'outils partagée en contenant un. Ici, l'élément de barre d'outils n'est pas du tout un élément script du point de vue du configurateur (c'est un simple libellé d'affichage de propriété), et la charge utile exécutable arrive via le contenu/frontmatter ordinaire d'une note — le même modèle de menace de contenu de coffre non fiable que les autres découvertes d'exécution de code via synchronisation/configuration Obsidian (obsidian-syncthing-integration, obsidian-codescript-toolkit).

Preuve de concept

Télécharger l’outil