Gửi #832401: thedotmack claude-mem v10.4.0 - Improper content hash construction - Field-boundary ambiguitythông tin

tiêu đềthedotmack claude-mem v10.4.0 - Improper content hash construction - Field-boundary ambiguity
Mô tả## Suggested CWE - CWE-682: Incorrect Calculation - Alternative: CWE-20: Improper Input Validation ## Suggested Severity - Severity: Medium - Suggested CVSS 3.1: `CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L` - Suggested score: 4.4 The vulnerability primarily affects integrity and availability of stored observations. It does not require breaking SHA-256; the collision is caused before hashing by ambiguous string concatenation. ## Summary Claude-Mem used a SHA-256 content hash to deduplicate observations, but the input to the hash was built by directly concatenating three independent fields: ```ts (memorySessionId || '') + (title || '') + (narrative || '') ``` Because no delimiter or length prefix separated the fields, different observation tuples could produce the same pre-hash string and therefore the same `content_hash`. An attacker able to influence observation fields could craft an observation that collides with another observation's deduplication key. The duplicate-detection logic could then treat a distinct legitimate observation as already stored, causing silent memory loss or poisoning of the persistent memory timeline. ## Technical Details The affected function used `(memory_session_id, title, narrative)` as the semantic identity of an observation. In affected versions, these fields were concatenated without any boundary marker before hashing: ```ts export function computeObservationContentHash( memorySessionId: string, title: string | null, narrative: string | null ): string { return createHash('sha256') .update((memorySessionId || '') + (title || '') + (narrative || '')) .digest('hex') .slice(0, 16); } ``` This makes different tuples indistinguishable when their concatenated representation is identical. For example: | memorySessionId | title | narrative | pre-hash string | |---|---|---|---| | `session-abc` | `debug log` | `""` | `session-abcdebug log` | | `session-ab` | `cdebug log` | `""` | `session-abcdebug log` | | `session-` | `abcdebug log` | `""` | `session-abcdebug log` | | `""` | `session-abcdebug log` | `""` | `session-abcdebug log` | In affected versions, all four tuples hash to the same 16-character `content_hash`. The observation store then uses that hash for deduplication, so a colliding observation can suppress a distinct observation. ## Proof of Concept The following standalone PoC demonstrates the pre-fix collision: ```js import { createHash } from 'crypto'; function vulnerableHash(memorySessionId, title, narrative) { return createHash('sha256') .update((memorySessionId || '') + (title || '') + (narrative || '')) .digest('hex') .slice(0, 16); } const tuples = [ ['session-abc', 'debug log', ''], ['session-ab', 'cdebug log', ''], ['session-', 'abcdebug log', ''], ['', 'session-abcdebug log', ''], ]; const hashes = tuples.map((tuple) => vulnerableHash(...tuple)); console.log(hashes); console.log(new Set(hashes).size); // vulnerable result: 1 ``` On an affected version, each tuple produces the same hash. If one tuple is stored first, a later distinct observation with another tuple can be incorrectly treated as a duplicate. ## Impact An attacker who can influence observation fields can create content-hash collisions without attacking SHA-256 itself. This can: - suppress legitimate observations during deduplication; - cause the memory timeline to retain attacker-controlled content instead of later legitimate content; - corrupt project memory used by future Claude-Mem sessions; - reduce integrity and availability of stored development history. This is a memory poisoning vector rather than arbitrary code execution. ## Fix PR #1494 fixes the issue by joining the hash fields with a null-byte delimiter, making field boundaries explicit: ```ts return createHash('sha256') .update([memorySessionId || '', title || '', narrative || ''].join('\x00')) .digest('hex') .slice(0, 16); ``` The PR also adds a regression test proving the previously colliding tuples now produce four distinct hashes. ## Timeline - 2026-02-23: Content-hash observation deduplication introduced. - 2026-03-26: Fix commit authored: `9cfa57d4984f068be8492be5489727ae04fa9203`. - 2026-03-26: PR #1494 opened. - 2026-04-07: PR #1494 merged. - 2026-04-07: Fix released in `v12.0.0`. ## Credits - Reporter / patch author: `3em0` - PR author: https://github.com/3em0 ## References - Pull request: https://github.com/thedotmack/claude-mem/pull/1494 - Fix commit: https://github.com/thedotmack/claude-mem/commit/9cfa57d4984f068be8492be5489727ae04fa9203 - Merge commit: https://github.com/thedotmack/claude-mem/commit/f32fda8b35e9fe9329f87da65c31149362a03f97 - Fixed release: https://github.com/thedotmack/claude-mem/releases/tag/v12.0.0 - Affected code before fix: https://github.com/thedotmack/claude-mem/blob/v11.0.1/src/services/sqlite/observations/store.ts - Fixed code: https://github.com/thedotmack/claude-mem/blob/v12.0.0/src/services/sqlite/observations/store.ts
Nguồn⚠️ https://github.com/thedotmack/claude-mem/pull/1494
Người dùng
 Dem00 (UID 84913)
Đệ trình18/05/2026 10:32 (cách đây 19 ngày)
Kiểm duyệt05/06/2026 08:56 (18 days later)
Trạng tháiđược chấp nhận
Mục VulDB368870 [thedotmack claude-mem đến 11.0.1 Observation Content Hash store.ts computeObservationContentHash mã hóa yếu]
điểm20

Do you know our Splunk app?

Download it now for free!