Skip to content
KitploitKITPLOIT
ИнструментыБлог
Log in
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

ЛентыКонтактыКонфиденциальность© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
obsidian-note-toolbar-PoC — PoC — выполнение произвольного JavaScript через frontmatter в Note Toolbar для Obsidian (GHSA-q8cw-3m8c-5pf2, CVE-2026-87002, CVSS 7.0). | Kitploit
Инструменты/GitHubGitHub/squeeze440/obsidian-note-toolbar-poc
Статический анализАнализ уязвимостейАнализ КодаЭксплуатацияЭксплуатация веб-приложенийСтатьи и ИсследованияОбучение и ОбразованиеРазработка Полезной Нагрузки
GitHub
squeeze440/obsidian-note-toolbar-poc

obsidian-note-toolbar-PoC

PoC — выполнение произвольного JavaScript через frontmatter в Note Toolbar для Obsidian (GHSA-q8cw-3m8c-5pf2, CVE-2026-87002, CVSS 7.0).

Репозиторий
2019 дней назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

Выполнение произвольного кода через frontmatter в Note Toolbar посредством цепочки переменных {{prop_NAME}} → {{js:}}

Статус CVE: запрошен, ожидает присвоения. Данная уязвимость опубликована как GHSA-q8cw-3m8c-5pf2. После присвоения CVE данный репозиторий будет переименован в CVE-YYYY-NNNNN-obsidian-note-toolbar-PoC, а этот баннер заменён ссылкой на CVE.

ИсследовательDostxodjayev Abdullox (@squeeze440)
AdvisoryGHSA-q8cw-3m8c-5pf2
CVSS 3.17.0 (High)
СлабостьCWE-94, CWE-1336

Выполнение произвольного кода через frontmatter в Note Toolbar посредством цепочки переменных {{prop_NAME}} → {{js:}}

Краткое описание

Ненадлежащая нейтрализация вывода в движке подстановки переменных Note Toolbar (плагин Obsidian) позволяет злоумышленнику, контролирующему YAML frontmatter заметки (например, участнику совместной работы в синхронизируемом/общем хранилище), добиться выполнения произвольного кода на машине жертвы при простом открытии заметки путём внедрения полезной нагрузки {{js: ...}} в свойство frontmatter, на которое ссылается уже существующий, не являющийся скриптовым элемент панели инструментов через {{prop_NAME}} в метке, всплывающей подсказке или ссылке.

Продукт

Note Toolbar (note-toolbar) — плагин сообщества Obsidian Репозиторий: https://github.com/chrisgurney/obsidian-note-toolbar

Протестированная версия

v1.34.12 (коммит 520271c3027eb6da38bab10a686b21e14c664c13, 2026-07-29), на Obsidian desktop 1.13.4 под Linux.

Оценка CVSS v3.1

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

  • AV:L — уязвимый компонент (JS-вычислитель плагина, работающий внутри Electron-рендерера Obsidian) не имеет сетевого интерфейса; полезная нагрузка поступает как локальное содержимое хранилища/файла, синхронизированное любым способом, который использует жертва (Git, Syncthing, Obsidian Sync, общая папка), что согласуется с предыдущими находками этого семейства (например, obsidian-syncthing-integration, obsidian-codescript-toolkit).
  • AC:H — эксплуатация зависит от условий, не контролируемых злоумышленником, которые должны уже существовать в установке жертвы: (1) настройка плагина "Scripting" должна быть уже включена (по умолчанию выключена), и (2) жертва должна уже иметь настроенный элемент панели инструментов, метка, всплывающая подсказка или ссылка которого является простой ссылкой {{prop_NAME}} на некоторый ключ frontmatter. Оба варианта являются реалистичными, документированными шаблонами использования, но ни один из них не является поведением по умолчанию.
  • PR:N — злоумышленнику не нужен доступ к системе жертвы, только возможность поместить заметку в хранилище жертвы с контролируемым злоумышленником frontmatter.
  • UI:R — жертва должна открыть/просмотреть конкретную заметку; клик по элементу панели инструментов не требуется, панель отображается автоматически.
  • S:U, C:H/I:H/A:H — код выполняется с полным доступом к Node.js (require('child_process'), файловая система и т. д.) от имени локальной учётной записи пользователя, запускающего Obsidian.

Подробности

Note Toolbar поддерживает документированную переменную {{prop_NAME}}, которая подставляет значение frontmatter заметки в метку, всплывающую подсказку или ссылку элемента панели инструментов (skills/note-toolbar-variables/SKILL.md, wiki Variables.md). Он также поддерживает переменную {{js: <expr>}}, которая вычисляет выражение как живой JavaScript, когда включена настройка плагина "Scripting".

Ошибка заключается в порядке операций в src/Toolbar/VariableResolver.ts::replaceVars():

  1. Строки 74–92: заполнители {{prop_KEY}} заменяются необработанным значением frontmatter[KEY] из текущей заметки — безусловно, независимо от настройки scriptingEnabled и независимо от источника этого значения frontmatter.
  2. Строки 94–104 (внутри if (this.ntb.settings.scriptingEnabled)): затем функция проверяет s.trim().startsWith('{{js:') для уже подставленной строки s, и если это так, удаляет обёртку {{js:/}} и передаёт остаток в JavaScriptAdapter.use() для вычисления.

Поскольку шаг 1 выполняется до шага 2 и перезаписывает s на месте, значение frontmatter, которое само начинается с {{js: и заканчивается на }}, повышается из "отображаемого текста" в "выполняемый скрипт" — даже несмотря на то, что элемент панели инструментов никогда не создавался как скриптовый элемент. Владелец элемента панели инструментов вводил только {{prop_status}}; исполняемая полезная нагрузка полностью поступает из frontmatter самой заметки.

JavaScriptAdapter.evaluate() (src/Adapters/JavaScriptAdapter.ts:143-205) выполняет выражение с помощью настоящего, не изолированного AsyncFunction:

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

Это подлинный конструктор AsyncFunction движка JS, а не интерпретатор/песочница — внутри Electron-рендерера Obsidian он имеет полный доступ к require()/Node.js, что подтверждено в PoC ниже через require('child_process').execSync(...).

Критически важно, что JS-адаптер встроен и не требует сопутствующего плагина (src/Adapters/AdapterManager.ts:59: adapter = this.js; // built-in, doesn't rely on plugin), в отличие от префиксов переменных Dataview/Templater/JS-Engine, для которых требуется установка этих плагинов. Его ограничивает только собственный переключатель "Scripting" плагина (scriptingEnabled, по умолчанию false, src/Settings/NoteToolbarSettings.ts:300).

Наконец, путь рендеринга, запускающий подстановку, является автоматическим, а не привязанным к клику: ToolbarRenderer.ts::renderLItems() вызывает this.ntb.vars.resolveText(toolbar, file) (src/Toolbar/ToolbarRenderer.ts:418) каждый раз, когда панель инструментов отображается для заметки — то есть при открытии/просмотре заметки — что разрешает метку и всплывающую подсказку каждого элемента через replaceVars(). Клик по затронутому элементу панели инструментов не требуется.

Само назначение панели инструментов заметке также управляется frontmatter (настройка toolbarProp, ключ по умолчанию notetoolbar, src/Settings/NoteToolbarSettings.ts:317), поэтому синхронизируемая заметка может выбирать, какая панель инструментов на ней отображается — но это не требуется для эксплуатации, если жертва уже использует панель инструментов по умолчанию или сопоставление папок, включающее уязвимый элемент.

Это отличается от риска, задокументированного в собственном SECURITY.md сопровождающего ("User scripts... executes JavaScript provided by the user... intentional and by design") — там описывается пользователь, сознательно создающий элемент панели инструментов {{js:}} или сознательно импортирующий общую конфигурацию панели инструментов, содержащую его. Здесь элемент панели инструментов вообще не является скриптовым элементом с точки зрения настройщика (это обычная метка отображения свойства), а исполняемая полезная нагрузка поступает через обычное содержимое/frontmatter заметки — та же модель угроз недоверенного содержимого хранилища, что и в других находках выполнения кода через синхронизацию/конфигурацию Obsidian (obsidian-syncthing-integration, obsidian-codescript-toolkit).

Доказательство концепции

Динамически проверено на реальном экземпляре Obsidian 1.13.4 desktop (Xvfb + fluxbox) с загрузкой фактического собранного плагина (main.js, собранный из проверенного исходного кода), а не извлечением отдельной функции.

Скачать инструмент