Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
obsidian-note-toolbar-PoC — PoC — execução arbitrária de JavaScript orientada por frontmatter no Note Toolbar para Obsidian (GHSA-q8cw-3m8c-5pf2, CVE-2026-87002, CVSS 7.0). | Kitploit
Ferramentas/GitHubGitHub/squeeze440/obsidian-note-toolbar-poc
Análise EstáticaAnálise de VulnerabilidadesAnálise de CódigoExploraçãoExploração de Aplicações WebPapers e PesquisaAprendizado e EducaçãoDesenvolvimento de Payloads
GitHub
squeeze440/obsidian-note-toolbar-poc

obsidian-note-toolbar-PoC

PoC — execução arbitrária de JavaScript orientada por frontmatter no Note Toolbar para Obsidian (GHSA-q8cw-3m8c-5pf2, CVE-2026-87002, CVSS 7.0).

Ver Repositório
há 7 diasAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

Execução de Código Arbitrário Orientada por Frontmatter no Note Toolbar via Cadeia de Variáveis {{prop_NAME}} → {{js:}}

Status do CVE: solicitado, aguardando atribuição. Esta descoberta está publicada como GHSA-q8cw-3m8c-5pf2. Após a atribuição do CVE, este repositório será renomeado CVE-YYYY-NNNNN-obsidian-note-toolbar-PoC e este banner será substituído pelo link do CVE.

PesquisadorDostxodjayev Abdullox (@squeeze440)
AvisoGHSA-q8cw-3m8c-5pf2
CVSS 3.17.0 (Alto)
FraquezaCWE-94, CWE-1336

Execução de Código Arbitrário Orientada por Frontmatter no Note Toolbar via Cadeia de Variáveis {{prop_NAME}} → {{js:}}

Resumo

A neutralização inadequada de saída no motor de substituição de variáveis do Note Toolbar (plugin do Obsidian) permite que um atacante que controla o frontmatter YAML de uma nota (por exemplo, um colaborador em um cofre sincronizado/compartilhado) alcance execução de código arbitrário na máquina da vítima quando a vítima simplesmente abre a nota, injetando um payload {{js: ...}} em uma propriedade de frontmatter que um item de barra de ferramentas pré-existente, não-script, referencia via {{prop_NAME}} em seu rótulo/tooltip/link.

Produto

Note Toolbar (note-toolbar) — plugin da comunidade Obsidian Repositório: https://github.com/chrisgurney/obsidian-note-toolbar

Versão Testada

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

CVSS v3.1 Estimado

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

  • AV:L — o componente vulnerável (o avaliador JS do plugin, executando dentro do renderer Electron do Obsidian) não é voltado à rede; o payload chega como conteúdo local de cofre/arquivo sincronizado por qualquer meio que a vítima utilize (Git, Syncthing, Obsidian Sync, pasta compartilhada), consistente com descobertas anteriores desta família (por exemplo, obsidian-syncthing-integration, obsidian-codescript-toolkit).
  • AC:H — a exploração depende de condições fora do controle do atacante que já devem existir na instalação da vítima: (1) a configuração "Scripting" do plugin já deve estar habilitada (desativada por padrão), e (2) a vítima já deve ter configurado um item de barra de ferramentas cujo rótulo, tooltip ou link seja uma referência {{prop_NAME}} pura a alguma chave de frontmatter. Ambas são padrões de uso realistas e documentados, mas nenhuma é o padrão.
  • PR:N — o atacante não precisa de acesso ao sistema da vítima, apenas da capacidade de colocar uma nota no cofre da vítima com frontmatter controlado pelo atacante.
  • UI:R — a vítima deve abrir/visualizar a nota específica; nenhum clique no item da barra de ferramentas é necessário, a barra de ferramentas é renderizada automaticamente.
  • S:U, C:H/I:H/A:H — o código executa com acesso total ao Node.js (require('child_process'), sistema de arquivos, etc.) como a conta de usuário local que executa o Obsidian.

Detalhes

O Note Toolbar suporta uma variável documentada {{prop_NAME}} que substitui o valor de frontmatter de uma nota no rótulo, tooltip ou link de um item da barra de ferramentas (skills/note-toolbar-variables/SKILL.md, wiki Variables.md). Também suporta uma variável {{js: <expr>}} que avalia a expressão como JavaScript ativo quando a configuração "Scripting" do plugin está habilitada.

O bug está na ordem das operações em src/Toolbar/VariableResolver.ts::replaceVars():

  1. Linhas 74–92: os placeholders {{prop_KEY}} são substituídos pelo valor bruto de frontmatter[KEY] da nota atual — incondicionalmente, independentemente da configuração scriptingEnabled, e independentemente da origem desse valor de frontmatter.
  2. Linhas 94–104 (dentro de if (this.ntb.settings.scriptingEnabled)): a função então verifica s.trim().startsWith('{{js:') na string s já substituída, e se verdadeiro, remove o invólucro {{js:/}} e passa o restante para JavaScriptAdapter.use() para avaliação.

Como o passo 1 executa antes do passo 2 e reescreve s no local, um valor de frontmatter que ele mesmo começa com {{js: e termina com }} é promovido de "texto exibido" para "script executado" — mesmo que o item da barra de ferramentas nunca tenha sido criado como um item de script. O proprietário do item da barra de ferramentas apenas digitou {{prop_status}}; o payload executável vem inteiramente do próprio frontmatter da nota.

JavaScriptAdapter.evaluate() (src/Adapters/JavaScriptAdapter.ts:143-205) executa a expressão com um AsyncFunction real e sem sandbox:

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));

Este é o construtor AsyncFunction genuíno do motor JS, não um interpretador/sandbox — dentro do renderer Electron do Obsidian isso tem acesso total a require()/Node.js, confirmado no PoC abaixo via require('child_process').execSync(...).

Crucialmente, o adaptador JS é integrado e não requer plugin complementar (src/Adapters/AdapterManager.ts:59: adapter = this.js; // built-in, doesn't rely on plugin), diferentemente dos prefixos de variável Dataview/Templater/JS-Engine que exigem esses plugins instalados. Apenas o próprio toggle "Scripting" do plugin (scriptingEnabled, padrão false, src/Settings/NoteToolbarSettings.ts:300) o controla.

Por fim, o caminho de renderização que dispara a substituição é automático, não condicionado a clique: ToolbarRenderer.ts::renderLItems() chama this.ntb.vars.resolveText(toolbar, file) (src/Toolbar/ToolbarRenderer.ts:418) toda vez que uma barra de ferramentas é renderizada para uma nota — ou seja, ao abrir/visualizar a nota — o que resolve o rótulo e o tooltip de cada item via replaceVars(). Nenhum clique no item da barra de ferramentas afetado é necessário.

A atribuição de barra de ferramentas para nota é ela mesma orientada por frontmatter (configuração toolbarProp, chave padrão notetoolbar, src/Settings/NoteToolbarSettings.ts:317), então uma nota sincronizada pode selecionar qual barra de ferramentas é renderizada nela — mas isso não é necessário para a exploração se a vítima já usa uma barra de ferramentas padrão ou mapeamento de pasta que inclua o item vulnerável.

Isso é distinto do risco que o próprio SECURITY.md do mantenedor documenta ("User scripts... executes JavaScript provided by the user... intentional and by design") — isso descreve um usuário criando conscientemente um item de barra de ferramentas {{js:}}, ou importando conscientemente uma configuração de barra de ferramentas compartilhada que contenha um. Aqui, o item da barra de ferramentas não é de forma alguma um item de script da perspectiva do configurador (é um rótulo simples de exibição de propriedade), e o payload executável chega via conteúdo/frontmatter comum de nota — o mesmo modelo de ameaça de conteúdo de cofre não confiável que outras descobertas de execução de código de sincronização/configuração do Obsidian (obsidian-syncthing-integration, obsidian-codescript-toolkit).

Prova de Conceito

Verificado dinamicamente contra uma instância real do Obsidian 1.13.4 desktop (Xvfb + fluxbox), carregando o plugin real compilado (main.js compilado a partir do código-fonte auditado), não uma extração de função isolada.

  1. Cofre PoCVault/ com 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 instalado, plugins da comunidade confiáveis, uma barra de ferramentas chamada "Toolbar" criada via a própria UI de Configurações do plugin com um único item cujo campo Label é {{prop_status}} (um rótulo simples de exibição de propriedade — nunca configurado como item de script).

  3. Configuração do plugin Scripting ativada (opt-in da vítima, desativada por padrão).

  4. Simplesmente abrir/visualizar Project Alpha.md — sem clique no item da barra de ferramentas — renderiza a barra de ferramentas mostrando ok (o valor de retorno da expressão JS), e os comandos de shell injetados executam de verdade:

    Prova no terminal (~/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
    

    Captura de tela do Obsidian mostrando o payload de frontmatter bruto e a barra de ferramentas renderizada com ok (~/engagements/obsidian-note-toolbar/evidence/01_obsidian_toolbar_rce_trigger.png).

    Nota de origem preservada em ~/engagements/obsidian-note-toolbar/evidence/poc_note_frontmatter.md.

Impacto

Execução de código arbitrário completa como o usuário local que executa o Obsidian, disparada por meramente abrir uma nota — sem clique, sem ação explícita de "executar script", sem diálogo. Em um fluxo de trabalho de equipe/cofre compartilhado (Obsidian Sync, cofre com Git, Syncthing, Google Drive, etc.), qualquer colaborador capaz de editar o frontmatter de uma nota pode alcançar RCE em todos os outros colaboradores que tenham a configuração Scripting do Note Toolbar habilitada e qualquer item de barra de ferramentas que exiba uma propriedade de nota.

Fraquezas (CWE)

  • CWE-94: Controle Inadequado da Geração de Código ('Injeção de Código') — dados de frontmatter não confiáveis são concatenados em uma string posteriormente interpretada como uma diretiva de script executável.
  • CWE-1336: Neutralização Inadequada de Elementos Especiais Usados em um Motor de Template — a sintaxe de template/variável {{...}} não neutraliza valores de substituição controlados pelo atacante que eles mesmos contêm outras diretivas de template.

Remediação

Em VariableResolver.replaceVars(), as verificações de prefixo de scripting ({{js:, {{dv:, {{jse:, <%/{{tp:) devem ser avaliadas contra a string original, pré-substituição, não a string após a substituição de {{prop_*}}/{{note_title}}/etc. ter sido executada — ou seja, determinar de antemão se o próprio item da barra de ferramentas foi criado como uma diretiva de script, e nunca permitir que um valor de frontmatter substituído seja reinterpretado como uma. Concretamente: realizar a verificação de prefixo de scripting no estilo hasVars antes do bloco de substituição PROP/SELECTION/NOTE_TITLE/etc., e pular a reverificação de startsWith('{{js:'/'{{dv:'/...) na string pós-substituição. Como defesa em profundidade, valores vindos do frontmatter também poderiam ser escapados/neutralizados para que nunca possam reentrar na gramática {{...}}.

Crédito

Dostxodjayev Abdullox

Canal de Relato

O SECURITY.md deste repositório confirma que o relato privado de vulnerabilidades do GitHub está habilitado e é o canal preferido ("GitHub private vulnerability reporting: use the 'Report a vulnerability' button under the Security tab of this repo"), com um formulário do Google como alternativa para relatores sem conta no GitHub. Reverificado de forma independente: 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 (nenhum aviso prévio, sem risco de duplicata).

Baixar ferramenta