CVE-2026-115478
obsidian-tc: Memory-lifecycle tools overwrite unowned notes or partially commit lifecycle changes
obsidian-tc is a governed, agent-ready Model Context Protocol server for Obsidian vaults. From 1.0.1 until 1.31.4, create_entity, link_entities, rename_entity, unlink_entities and delete_entity regenerate memory notes from SQLite at the computed memory/<type>/<name>.md path without reliably preserving note ownership or the consistency of a failed lifecycle operation. During shared materialization, a hand-authored note or an orphan left by a different entity whose name sanitized to the same path could have its entire body overwritten on the next write naming that type and name, with non-owned frontmatter preserved. rename_entity also seeded the destination path with a direct atomic write without validating ownership and could overwrite a foreign note there. Separately, several tools mutated SQLite before fallible filesystem work: create_entity and link_entities inserted the row or relation before materialization; rename_entity updated the entity, including a retired status, before updating its note; unlink_entities removed a relation before rematerializing the source note; and delete_entity's cascade removed the target and its relations before rematerializing neighbouring notes. A later filesystem failure could therefore leave a row or relation changed and the memory graph inconsistent with the notes on disk even when the operation failed. An authorized caller with the required memory-tool permissions could, without intending to, destroy the body of a vault note outside the entity being written; delete_entity additionally requires its deletion permission and destructive confirmation, which this memory flaw does not bypass. Snapshots-before-write through restore_note mitigate the overwrite only where snapshots are enabled and the note had previously been written through obsidian-tc. This issue is fixed in version 1.31.4.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- High
- Availability
- Low
Exploit likelihood
What each source reports
CVE List Score used
7.1
obsidian-tc: Memory-lifecycle tools overwrite unowned notes or partially commit lifecycle changes
obsidian-tc is a governed, agent-ready Model Context Protocol server for Obsidian vaults. From 1.0.1 until 1.31.4, create_entity, link_entities, rename_entity, unlink_entities and delete_entity regenerate memory notes from SQLite at the computed memory/<type>/<name>.md path without reliably preserving note ownership or the consistency of a failed lifecycle operation. During shared materialization, a hand-authored note or an orphan left by a different entity whose name sanitized to the same path could have its entire body overwritten on the next write naming that type and name, with non-owned frontmatter preserved. rename_entity also seeded the destination path with a direct atomic write without validating ownership and could overwrite a foreign note there. Separately, several tools mutated SQLite before fallible filesystem work: create_entity and link_entities inserted the row or relation before materialization; rename_entity updated the entity, including a retired status, before updating its note; unlink_entities removed a relation before rematerializing the source note; and delete_entity's cascade removed the target and its relations before rematerializing neighbouring notes. A later filesystem failure could therefore leave a row or relation changed and the memory graph inconsistent with the notes on disk even when the operation failed. An authorized caller with the required memory-tool permissions could, without intending to, destroy the body of a vault note outside the entity being written; delete_entity additionally requires its deletion permission and destructive confirmation, which this memory flaw does not bypass. Snapshots-before-write through restore_note mitigate the overwrite only where snapshots are enabled and the note had previously been written through obsidian-tc. This issue is fixed in version 1.31.4.
- Record
CVE-2026-115478- CVSS 4.0
- 7.1 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:L/SC:N/SI:N/SA:N - Weakness
- CWE-459, CWE-863
- Updated
- 2026-11-02
EUVDEUVD-2026-109083
7.1
obsidian-tc is a governed, agent-ready Model Context Protocol server for Obsidian vaults. From 1.0.1 until 1.31.4, create_entity, link_entities, rename_entity, unlink_entities and delete_entity regenerate memory notes from SQLite at the computed memory/<type>/<name>.md path without reliably preserving note ownership or the consistency of a failed lifecycle operation. During shared materialization, a hand-authored note or an orphan left by a different entity whose name sanitized to the same path could have its entire body overwritten on the next write naming that type and name, with non-owned frontmatter preserved. rename_entity also seeded the destination path with a direct atomic write without validating ownership and could overwrite a foreign note there. Separately, several tools mutated SQLite before fallible filesystem work: create_entity and link_entities inserted the row or relation before materialization; rename_entity updated the entity, including a retired status, before updating its note; unlink_entities removed a relation before rematerializing the source note; and delete_entity's cascade removed the target and its relations before rematerializing neighbouring notes. A later filesystem failure could therefore leave a row or relation changed and the memory graph inconsistent with the notes on disk even when the operation failed. An authorized caller with the required memory-tool permissions could, without intending to, destroy the body of a vault note outside the entity being written; delete_entity additionally requires its deletion permission and destructive confirmation, which this memory flaw does not bypass. Snapshots-before-write through restore_note mitigate the overwrite only where snapshots are enabled and the note had previously been written through obsidian-tc. This issue is fixed in version 1.31.4.
- Record
EUVD-2026-109083- CVSS 4.0
- 7.1 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:L/SC:N/SI:N/SA:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-r3g7-r4hr-m258
7.1
obsidian-tc: Memory-lifecycle tools overwrite unowned notes or partially commit lifecycle changes
Summary
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. Separately, several of these tools inserted or removed their SQLite row before the fallible filesystem step, so a refused note write could leave a relation gone, a retired status committed, or the wrong entity deleted.
Details
create_entityandlink_entitiesinserted the SQL row or relation before materialization.rename_entityseeded the destination path with a direct atomic write that bypassed the ownership check, and for a status-only rename could commit a retired status with the note write refused.unlink_entitiesremoved the relation row before discovering the source note's rematerialization would be refused.delete_entity's cascade could delete the target and its relations before a neighbour's note was found to be foreign.
The overwrite exists in every released version since materializeEntity shipped (git show v1.0.1:packages/server/src/memory/materialize.ts).
Impact
An authorized caller with memory-write scope (any agent using the M5 memory tools) can, without intending to, destroy the body of a vault note outside the entity it is writing, and can leave the memory graph inconsistent with the notes on disk. Snapshots-before-write (restore_note) mitigate the overwrite only where snapshots are enabled and the note had been written through obsidian-tc before.
Patches
Fixed in 1.31.4 at the shared primitive: materializeEntity refuses to write over a note whose obsidian_tc_id is missing or belongs to another entity; a new assertNoteOwnership pre-check runs before any SQLite mutation in the three lifecycle tools, so a refusal is a no-op; create_entity and link_entities roll back the row they had inserted. Verified by test/m5-memory-ownership.test.ts, which covers all five call sites and the rollback.
Workarounds
None that preserve the tools. Disabling the write:memory scope for callers prevents the write path entirely.
Credit
Found by the maintainer while building obsidian-tc memory import (PR #978); the vulnerability class was independently confirmed by a cross-vendor adversarial review.
References
- PR #978 (fix and test), CHANGELOG
## [1.31.4] ### Security packages/server/src/memory/materialize.ts,packages/server/src/tools/m5/memory-lifecycle-tools.ts
- Record
GHSA-r3g7-r4hr-m258- CVSS 4.0
- 7.1 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:L/SC:N/SI:N/SA:N - Weakness
- CWE-459, CWE-863
- Updated
- 2026-11-02
NVD
7.1
obsidian-tc is a governed, agent-ready Model Context Protocol server for Obsidian vaults. From 1.0.1 until 1.31.4, create_entity, link_entities, rename_entity, unlink_entities and delete_entity regenerate memory notes from SQLite at the computed memory/<type>/<name>.md path without reliably preserving note ownership or the consistency of a failed lifecycle operation. During shared materialization, a hand-authored note or an orphan left by a different entity whose name sanitized to the same path could have its entire body overwritten on the next write naming that type and name, with non-owned frontmatter preserved. rename_entity also seeded the destination path with a direct atomic write without validating ownership and could overwrite a foreign note there. Separately, several tools mutated SQLite before fallible filesystem work: create_entity and link_entities inserted the row or relation before materialization; rename_entity updated the entity, including a retired status, before updating its note; unlink_entities removed a relation before rematerializing the source note; and delete_entity's cascade removed the target and its relations before rematerializing neighbouring notes. A later filesystem failure could therefore leave a row or relation changed and the memory graph inconsistent with the notes on disk even when the operation failed. An authorized caller with the required memory-tool permissions could, without intending to, destroy the body of a vault note outside the entity being written; delete_entity additionally requires its deletion permission and destructive confirmation, which this memory flaw does not bypass. Snapshots-before-write through restore_note mitigate the overwrite only where snapshots are enabled and the note had previously been written through obsidian-tc. This issue is fixed in version 1.31.4.
- Record
CVE-2026-115478- CVSS 4.0
- 7.1 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - Weakness
- CWE-459, CWE-863
- Updated
- 2026-11-02
OSV
7.1
obsidian-tc: Memory-lifecycle tools overwrite unowned notes or partially commit lifecycle changes
obsidian-tc is a governed, agent-ready Model Context Protocol server for Obsidian vaults. From 1.0.1 until 1.31.4, create_entity, link_entities, rename_entity, unlink_entities and delete_entity regenerate memory notes from SQLite at the computed memory/<type>/<name>.md path without reliably preserving note ownership or the consistency of a failed lifecycle operation. During shared materialization, a hand-authored note or an orphan left by a different entity whose name sanitized to the same path could have its entire body overwritten on the next write naming that type and name, with non-owned frontmatter preserved. rename_entity also seeded the destination path with a direct atomic write without validating ownership and could overwrite a foreign note there. Separately, several tools mutated SQLite before fallible filesystem work: create_entity and link_entities inserted the row or relation before materialization; rename_entity updated the entity, including a retired status, before updating its note; unlink_entities removed a relation before rematerializing the source note; and delete_entity's cascade removed the target and its relations before rematerializing neighbouring notes. A later filesystem failure could therefore leave a row or relation changed and the memory graph inconsistent with the notes on disk even when the operation failed. An authorized caller with the required memory-tool permissions could, without intending to, destroy the body of a vault note outside the entity being written; delete_entity additionally requires its deletion permission and destructive confirmation, which this memory flaw does not bypass. Snapshots-before-write through restore_note mitigate the overwrite only where snapshots are enabled and the note had previously been written through obsidian-tc. This issue is fixed in version 1.31.4.
- Record
CVE-2026-115478- CVSS 4.0
- 7.1 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:L/SC:N/SI:N/SA:N - Weakness
- CWE-459, CWE-863
- Updated
- 2026-11-02
OSVGHSA-r3g7-r4hr-m258
7.1
obsidian-tc: Memory-lifecycle tools overwrite unowned notes or partially commit lifecycle changes
Summary
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. Separately, several of these tools inserted or removed their SQLite row before the fallible filesystem step, so a refused note write could leave a relation gone, a retired status committed, or the wrong entity deleted.
Details
create_entityandlink_entitiesinserted the SQL row or relation before materialization.rename_entityseeded the destination path with a direct atomic write that bypassed the ownership check, and for a status-only rename could commit a retired status with the note write refused.unlink_entitiesremoved the relation row before discovering the source note's rematerialization would be refused.delete_entity's cascade could delete the target and its relations before a neighbour's note was found to be foreign.
The overwrite exists in every released version since materializeEntity shipped (git show v1.0.1:packages/server/src/memory/materialize.ts).
Impact
An authorized caller with memory-write scope (any agent using the M5 memory tools) can, without intending to, destroy the body of a vault note outside the entity it is writing, and can leave the memory graph inconsistent with the notes on disk. Snapshots-before-write (restore_note) mitigate the overwrite only where snapshots are enabled and the note had been written through obsidian-tc before.
Patches
Fixed in 1.31.4 at the shared primitive: materializeEntity refuses to write over a note whose obsidian_tc_id is missing or belongs to another entity; a new assertNoteOwnership pre-check runs before any SQLite mutation in the three lifecycle tools, so a refusal is a no-op; create_entity and link_entities roll back the row they had inserted. Verified by test/m5-memory-ownership.test.ts, which covers all five call sites and the rollback.
Workarounds
None that preserve the tools. Disabling the write:memory scope for callers prevents the write path entirely.
Credit
Found by the maintainer while building obsidian-tc memory import (PR #978); the vulnerability class was independently confirmed by a cross-vendor adversarial review.
References
- PR #978 (fix and test), CHANGELOG
## [1.31.4] ### Security packages/server/src/memory/materialize.ts,packages/server/src/tools/m5/memory-lifecycle-tools.ts
- Record
GHSA-r3g7-r4hr-m258- CVSS 4.0
- 7.1 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:L/SC:N/SI:N/SA:N - Weakness
- CWE-459, CWE-863
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
obsidian-tcnpm |
1.0.1 to 1.31.3 | 1.31.4 |
obsidian-tcnpm |
1.0.1 up to 1.31.4 | 1.31.4 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-115478 is a high vulnerability (CVSS 7.1) in The-40-thieves Obsidian-tc, published October 23, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.32%, the 25th percentile. Fixed in obsidian-tc 1.31.4.
References
github.com/The-40-Thieves/obsidian-tc/security/advisories/GHSA-r3g7-r4hr-m258
github.com/The-40-Thieves/obsidian-tc/pull/978
github.com/The-40-Thieves/obsidian-tc/commit/99f7914ca0fbeed92e7c4d39cc8c3e5830dab133
github.com/The-40-Thieves/obsidian-tc/blob/v1.31.4/CHANGELOG.md
github.com/The-40-Thieves/obsidian-tc/releases/tag/v1.31.4
nvd.nist.gov/vuln/detail/CVE-2026-115478
github.com/advisories/GHSA-r3g7-r4hr-m258
github.com/CVEProject/cvelistV5/tree/main/cves/2026/115xxx/CVE-2026-115478.json
github.com/The-40-Thieves/obsidian-tc