Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
obsidian-note-toolbar-PoC — PoC — esecuzione arbitraria di JavaScript guidata dal frontmatter in Note Toolbar per Obsidian (GHSA-q8cw-3m8c-5pf2, CVE-2026-87002, CVSS 7.0). | Kitploit
Strumenti/GitHubGitHub/squeeze440/obsidian-note-toolbar-poc
Analisi StaticaAnalisi delle VulnerabilitàAnalisi del CodiceExploitSfruttamento di Applicazioni WebPaper e RicercaApprendimento e FormazioneSviluppo Payload
GitHub
squeeze440/obsidian-note-toolbar-poc

obsidian-note-toolbar-PoC

PoC — esecuzione arbitraria di JavaScript guidata dal frontmatter in Note Toolbar per Obsidian (GHSA-q8cw-3m8c-5pf2, CVE-2026-87002, CVSS 7.0).

Vedi Repository
7 giorni faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

Esecuzione di codice arbitrario guidata dal frontmatter in Note Toolbar tramite la catena di variabili {{prop_NAME}} → {{js:}}

Stato CVE: richiesto, in attesa di assegnazione. Questa segnalazione è pubblicata come GHSA-q8cw-3m8c-5pf2. All'assegnazione del CVE questo repository viene rinominato CVE-YYYY-NNNNN-obsidian-note-toolbar-PoC e questo banner viene sostituito con il link al CVE.

RicercatoreDostxodjayev Abdullox (@squeeze440)
AdvisoryGHSA-q8cw-3m8c-5pf2
CVSS 3.17.0 (Alto)
DebolezzaCWE-94, CWE-1336

Esecuzione di codice arbitrario guidata dal frontmatter in Note Toolbar tramite la catena di variabili {{prop_NAME}} → {{js:}}

Riepilogo

Una neutralizzazione impropria dell'output nel motore di sostituzione delle variabili di Note Toolbar (plugin per Obsidian) consente a un attaccante che controlla il frontmatter YAML di una nota (ad esempio un collaboratore su un vault sincronizzato/condiviso) di ottenere l'esecuzione di codice arbitrario sulla macchina della vittima quando questa si limita ad aprire la nota, iniettando un payload {{js: ...}} in una proprietà del frontmatter a cui fa riferimento l'etichetta/tooltip/link di un elemento della toolbar preesistente e non-script tramite {{prop_NAME}}.

Prodotto

Note Toolbar (note-toolbar) — plugin della community di Obsidian Repository: https://github.com/chrisgurney/obsidian-note-toolbar

Versione testata

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

CVSS v3.1 stimato

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

  • AV:L — il componente vulnerabile (il valutatore JS del plugin, in esecuzione all'interno del renderer Electron di Obsidian) non è esposto alla rete; il payload arriva come contenuto locale del vault/file sincronizzato con qualunque mezzo utilizzi la vittima (Git, Syncthing, Obsidian Sync, cartella condivisa), coerentemente con precedenti segnalazioni di questa famiglia (ad es. obsidian-syncthing-integration, obsidian-codescript-toolkit).
  • AC:H — lo sfruttamento dipende da condizioni fuori dal controllo dell'attaccante che devono già esistere sull'installazione della vittima: (1) l'impostazione "Scripting" del plugin deve essere già abilitata (disattivata per impostazione predefinita), e (2) la vittima deve aver già configurato un elemento della toolbar la cui etichetta, tooltip o link sia un riferimento {{prop_NAME}} nudo a una qualche chiave del frontmatter. Entrambe sono modalità d'uso realistiche e documentate, ma nessuna delle due è quella predefinita.
  • PR:N — l'attaccante non necessita di alcun accesso al sistema della vittima, solo della capacità di far giungere una nota nel vault della vittima con un frontmatter controllato dall'attaccante.
  • UI:R — la vittima deve aprire/visualizzare la nota specifica; non è richiesto alcun clic sull'elemento della toolbar, la toolbar viene renderizzata automaticamente.
  • S:U, C:H/I:H/A:H — il codice viene eseguito con pieno accesso a Node.js (require('child_process'), filesystem, ecc.) come account utente locale che esegue Obsidian.

Dettagli

Note Toolbar supporta una variabile documentata {{prop_NAME}} che sostituisce il valore del frontmatter di una nota nell'etichetta, nel tooltip o nel link di un elemento della toolbar (skills/note-toolbar-variables/SKILL.md, wiki Variables.md). Supporta inoltre una variabile {{js: <expr>}} che valuta l'espressione come JavaScript live quando l'impostazione "Scripting" del plugin è abilitata.

Il bug risiede nell'ordine delle operazioni in src/Toolbar/VariableResolver.ts::replaceVars():

  1. Righe 74–92: i segnaposto {{prop_KEY}} vengono sostituiti con il valore grezzo di frontmatter[KEY] dalla nota corrente — incondizionatamente, indipendentemente dall'impostazione scriptingEnabled, e indipendentemente dalla fonte di quel valore del frontmatter.
  2. Righe 94–104 (all'interno di if (this.ntb.settings.scriptingEnabled)): la funzione verifica poi s.trim().startsWith('{{js:') sulla stringa s già sostituita, e se vera rimuove il wrapper {{js:/}} e passa il resto a JavaScriptAdapter.use() per la valutazione.

Poiché il passo 1 viene eseguito prima del passo 2 e riscrive s sul posto, un valore del frontmatter che inizia esso stesso con {{js: e termina con }} viene promosso da "testo visualizzato" a "script eseguito" — anche se l'elemento della toolbar non è mai stato creato come elemento script. Il proprietario dell'elemento della toolbar ha digitato solo {{prop_status}}; il payload eseguibile proviene interamente dal frontmatter della nota stessa.

JavaScriptAdapter.evaluate() (src/Adapters/JavaScriptAdapter.ts:143-205) esegue l'espressione con un vero AsyncFunction non sandboxato:

root@kitploit:~
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));

Questo è il costruttore AsyncFunction autentico del motore JS, non un interprete/sandbox — all'interno del renderer Electron di Obsidian ha pieno accesso a require()/Node.js, confermato nel PoC sottostante tramite require('child_process').execSync(...).

Fondamentalmente, l'adapter JS è integrato e non richiede alcun plugin complementare (src/Adapters/AdapterManager.ts:59: adapter = this.js; // built-in, doesn't rely on plugin), a differenza dei prefissi di variabile Dataview/Templater/JS-Engine che richiedono l'installazione di quei plugin. Solo l'interruttore "Scripting" del plugin stesso (scriptingEnabled, predefinito false, src/Settings/NoteToolbarSettings.ts:300) lo controlla.

Infine, il percorso di rendering che attiva la sostituzione è automatico, non vincolato a un clic: ToolbarRenderer.ts::renderLItems() chiama this.ntb.vars.resolveText(toolbar, file) (src/Toolbar/ToolbarRenderer.ts:418) ogni volta che una toolbar viene renderizzata per una nota — cioè all'apertura/visualizzazione della nota — il che risolve l'etichetta e il tooltip di ogni elemento tramite replaceVars(). Non è richiesto alcun clic sull'elemento della toolbar interessato.

L'assegnazione toolbar-nota è essa stessa guidata dal frontmatter (impostazione toolbarProp, chiave predefinita notetoolbar, src/Settings/NoteToolbarSettings.ts:317), quindi una nota sincronizzata può selezionare quale toolbar viene renderizzata su di essa — ma ciò non è necessario per lo sfruttamento se la vittima utilizza già una toolbar predefinita o una mappatura di cartella che include l'elemento vulnerabile.

Questo è distinto dal rischio documentato nel SECURITY.md dello stesso manutentore ("User scripts... executes JavaScript provided by the user... intentional and by design") — quello descrive un utente che crea consapevolmente un elemento della toolbar {{js:}}, o che importa consapevolmente una configurazione di toolbar condivisa che ne contiene uno. Qui, l'elemento della toolbar non è affatto un elemento script dal punto di vista di chi lo configura (è una semplice etichetta di visualizzazione di proprietà), e il payload eseguibile arriva tramite il normale contenuto/frontmatter della nota — lo stesso modello di minaccia di contenuto di vault non attendibile di altre segnalazioni di esecuzione di codice da sync/config di Obsidian (obsidian-syncthing-integration, obsidian-codescript-toolkit).

Proof of Concept

Verificato dinamicamente su una reale istanza desktop di Obsidian 1.13.4 (Xvfb + fluxbox), caricando il plugin effettivamente compilato (main.js compilato dal sorgente verificato), non una semplice estrazione di funzione.

  1. Vault PoCVault/ con Project Alpha.md:

    root@kitploit:~
    ---
    status: "{{js: require('child_process').execSync('id > /tmp/ntb_poc_proof.txt; date >> /tmp/ntb_poc_proof.txt; whoami >> /tmp/ntb_poc_proof.txt'); return 'ok';}}"
    notetoolbar: Toolbar
    ---
    
  2. Plugin Note Toolbar installato, plugin della community considerati attendibili, una toolbar denominata "Toolbar" creata tramite l'interfaccia Impostazioni del plugin stesso con un singolo elemento il cui campo Label è {{prop_status}} (una semplice etichetta di visualizzazione di proprietà — mai configurata come elemento script).

  3. Impostazione del plugin Scripting attivata (opt-in della vittima, disattivata per impostazione predefinita).

  4. Semplicemente aprendo/visualizzando Project Alpha.md — nessun clic sull'elemento della toolbar — viene renderizzata la toolbar che mostra ok (il valore di ritorno dell'espressione JS), e i comandi shell iniettati vengono eseguiti realmente:

    Prova da terminale (~/engagements/obsidian-note-toolbar/evidence/02_terminal_proof_of_execution.png):

    root@kitploit:~
    $ cat /tmp/ntb_poc_proof.txt
    uid=1000(kali) gid=1000(kali) groups=1000(kali),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),100(users),105(docker),992(kvm)
    Fri Jul 31 09:31:33 PM +05 2026
    kali
    

    Screenshot di Obsidian che mostra il payload grezzo del frontmatter e la toolbar renderizzata ok (~/engagements/obsidian-note-toolbar/evidence/01_obsidian_toolbar_rce_trigger.png).

    Nota sorgente conservata in ~/engagements/obsidian-note-toolbar/evidence/poc_note_frontmatter.md.

Impatto

Piena esecuzione di codice arbitrario come utente locale che esegue Obsidian, attivata dal semplice aprire una nota — nessun clic, nessuna azione esplicita di "esegui script", nessun dialogo. In un flusso di lavoro di team/vault condiviso (Obsidian Sync, vault basato su Git, Syncthing, Google Drive, ecc.), qualsiasi collaboratore in grado di modificare il frontmatter di una nota può ottenere RCE su ogni altro collaboratore che ha l'impostazione Scripting di Note Toolbar abilitata e un qualsiasi elemento della toolbar che visualizza una proprietà della nota.

Debolezze (CWE)

  • CWE-94: Controllo improprio della generazione di codice ('Code Injection') — dati non attendibili del frontmatter vengono concatenati in una stringa successivamente interpretata come direttiva di script eseguibile.
  • CWE-1336: Neutralizzazione impropria di elementi speciali usati in un motore di template — la sintassi di template/variabile {{...}} non neutralizza i valori di sostituzione controllati dall'attaccante che contengono essi stessi ulteriori direttive di template.

Remediation

In VariableResolver.replaceVars(), i controlli del prefisso di scripting ({{js:, {{dv:, {{jse:, <%/{{tp:) dovrebbero essere valutati sulla stringa originale, pre-sostituzione, non sulla stringa dopo che la sostituzione di {{prop_*}}/{{note_title}}/ecc. è stata eseguita — cioè determinare in anticipo se l'elemento della toolbar stesso è stato creato come direttiva di script, e non permettere mai che un valore del frontmatter sostituito venga reinterpretato come tale. Concretamente: eseguire il controllo del prefisso di scripting in stile hasVars prima del blocco di sostituzione PROP/SELECTION/NOTE_TITLE/ecc., e saltare il ricontrollo di startsWith('{{js:'/'{{dv:'/...) sulla stringa post-sostituzione. Come difesa in profondità, i valori provenienti dal frontmatter potrebbero anche essere sottoposti a escape/neutralizzati in modo che non possano mai rientrare nella grammatica {{...}}.

Crediti

Dostxodjayev Abdullox

Canale di segnalazione

Il SECURITY.md di questo repository conferma che la segnalazione privata di vulnerabilità su GitHub è abilitata ed è il canale preferito ("GitHub private vulnerability reporting: use the 'Report a vulnerability' button under the Security tab of this repo"), con un modulo Google come fallback per i segnalatori senza account GitHub. Riverificato in modo indipendente: gh api repos/chrisgurney/obsidian-note-toolbar/private-vulnerability-reporting --jq .enabled → true, e gh api repos/chrisgurney/obsidian-note-toolbar/security-advisories --jq 'length' → 0 (nessun advisory precedente, nessun rischio di duplicazione).

Scarica lo strumento