Advisories for Npm/Obsidian-Tc package

2026

obsidian-tc: Memory-lifecycle tools overwrite unowned notes or partially commit lifecycle changes

create_entity, link_entities, rename_entity, unlink_entities and delete_entity regenerate a memory note's body from SQLite at the computed memory/<type>/<name>.md path. When a note already existed at that path and was not owned by the entity being written (a hand-authored note, or an orphan left by a different entity whose name sanitized to the same path), its entire body was overwritten on the next write naming that (type, name), keeping only its frontmatter. …

obsidian-tc: Default folder ACL is fail-open; .obsidian plugin secrets are readable by default

With a default configuration, an undefined readPaths/writePaths meant allow-all, the strictReadDefault flag was inert, and the .obsidian/.git/.trash control directories were denied only during enumeration — not on the direct request path. A caller could read .obsidian/plugins/*/data.json, exfiltrating plugin API keys and Obsidian Sync passwords (live-reproduced), as well as any other in-vault file by path.

obsidian-tc: Declined human-in-the-loop confirmations can permit destructive calls over HTTP

On a Streamable HTTP deployment with auth.jwtSecret configured, serving a 2026-07-28-era client that declared elicitation.form support, a call to a dispatch-gated tool (destructive: true, or a scope with an HITL floor) that was offered an inputRequired confirmation could still complete after the human declined, cancelled, or the elicitation response was omitted or malformed, provided the client echoed the validly bound requestState on resubmission. The server trusted an authentic, call-bound state …

obsidian-tc tokens can access arbitrary configured vaults

Tool dispatch did not check the caller-supplied input.vault against the caller's bound vault (ctx.vaultId); the folder ACL was a single global instance and the JWT carried no vault claim. As a result, any valid token could read, write, or delete any configured vault by passing input.vault, defeating multi-tenant isolation across ~90 tool sites. (resources/read was the only surface that already guarded this.)

obsidian-tc HTTP transport lacks Origin/DNS-rebinding protection, enabling drive-by vault access on loopback

The Streamable HTTP transport was constructed without enableDnsRebindingProtection/allowedHosts/allowedOrigins and performed no Origin-header validation. With the documented auth.mode: "none" loopback default, a drive-by web page could POST http://127.0.0.1/mcp and receive caller http-local with scopes ["*"] — full vault read/write — via DNS rebinding / a forged Origin.

obsidian-tc Bridge tools leak denied-note data via unfiltered sibling fields

Bridge tool results filtered only the items array against the read ACL and passed sibling fields through unfiltered: tasks_filter emitted groups whose counts reflected denied notes, makemd_query returned …result siblings, and list_templates enumerated Templater template paths and parsed user-function bodies with no read-whitelist gate. A caller could infer or read data from notes outside its read ACL.