Conversation
Six advisory drafts, one per vulnerability fixed in v0.8.2. These match the content that should be published via GitHub's Security Advisories UI at: https://github.com/rohitg00/agentmemory/security/advisories/new Each advisory includes: - Severity + CVSS 3.1 vector - CWE classification - Affected/patched version ranges - Full summary of the issue - Impact analysis - Patch description with commit reference - Workarounds for users on affected versions - References and credit These drafts are reference material — the actual CVEs need to be filed through the GitHub UI to get GHSA IDs assigned and to appear in GitHub's vulnerability database for downstream scanners. Order: 01. viewer-xss (CRITICAL, 9.6) 02. curl-sh-rce (CRITICAL, 9.8) 03. default-bind-0000 (HIGH, 8.1) 04. mesh-unauth (HIGH, 7.4) 05. obsidian-export-traversal (MEDIUM, 6.5) 06. privacy-redaction-incomplete (MEDIUM, 6.2)
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
✅ Files skipped from review due to trivial changes (2)
📝 WalkthroughWalkthroughSix new GitHub security advisories were added, documenting vulnerabilities in agentmemory < 0.8.2: viewer stored XSS, CLI remote shell execution, insecure default bindings, unauthenticated mesh sync, Obsidian export path traversal, and incomplete privacy redaction. Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
.github/security-advisories/03-default-bind-0000.md (1)
18-19: Avoid hardcoding total endpoint count in the advisory textLine 18’s “All 109 other REST endpoints” can go stale and weaken advisory accuracy over time. Prefer “all other REST endpoints” unless this count is generated/verified at publish time.
Suggested wording tweak
-- All 109 other REST endpoints +- All other REST endpoints🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/security-advisories/03-default-bind-0000.md around lines 18 - 19, Replace the hardcoded phrase "All 109 other REST endpoints" with a non-counted phrase like "all other REST endpoints" (or generate/verify the count at publish time if you must keep a numeric total) so the advisory text cannot go stale; update the sentence containing the string "All 109 other REST endpoints" accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/security-advisories/04-mesh-unauth.md:
- Around line 26-27: The advisory text incorrectly states "All 4 mesh REST
endpoints" while listing five endpoints (`mesh-register`, `mesh-list`,
`mesh-sync`, `mesh-receive`, `mesh-export`); update the count to "All 5 mesh
REST endpoints" (or remove the numeric count) so it matches the listed
endpoints, and ensure the second bullet referencing `mem::mesh-sync` remains
accurate about the new `meshAuthToken` parameter and refusal to sync when
missing.
In @.github/security-advisories/05-obsidian-export-traversal.md:
- Around line 33-42: resolveVaultDir in src/functions/obsidian-export.ts
currently uses path.resolve + a prefix check which does not follow symlinks,
allowing symlink-based traversal; update resolveVaultDir to perform symlink-safe
resolution (e.g., use fs.realpathSync on the resolved path and the
AGENTMEMORY_EXPORT_ROOT, or verify with lstat to ensure no path component inside
the root is a symlink that points outside) and ensure mkdir/writeFile calls
operate on the realpath result; update tests in test/obsidian-export.test.ts to
include a symlink escape case and assert the endpoint returns the same rejection
({ success: false, error: "vaultDir must be inside AGENTMEMORY_EXPORT_ROOT" })
when a symlink inside the root points outside.
---
Nitpick comments:
In @.github/security-advisories/03-default-bind-0000.md:
- Around line 18-19: Replace the hardcoded phrase "All 109 other REST endpoints"
with a non-counted phrase like "all other REST endpoints" (or generate/verify
the count at publish time if you must keep a numeric total) so the advisory text
cannot go stale; update the sentence containing the string "All 109 other REST
endpoints" accordingly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: f8a8ac76-fbbc-4b32-955a-087155088d28
📒 Files selected for processing (6)
.github/security-advisories/01-viewer-xss.md.github/security-advisories/02-curl-sh-rce.md.github/security-advisories/03-default-bind-0000.md.github/security-advisories/04-mesh-unauth.md.github/security-advisories/05-obsidian-export-traversal.md.github/security-advisories/06-privacy-redaction-incomplete.md
| - All 4 mesh REST endpoints (`mesh-register`, `mesh-list`, `mesh-sync`, `mesh-receive`, `mesh-export`) now return 503 with `"mesh requires AGENTMEMORY_SECRET"` if the secret is not configured | ||
| - The `mem::mesh-sync` function now accepts a `meshAuthToken` parameter and **refuses to sync at all** if the token is missing |
There was a problem hiding this comment.
Fix endpoint-count mismatch in patch summary
Line 26 says “All 4 mesh REST endpoints” but five endpoints are listed. Please correct the count to avoid ambiguity in the advisory record.
Suggested fix
-- All 4 mesh REST endpoints (`mesh-register`, `mesh-list`, `mesh-sync`, `mesh-receive`, `mesh-export`) now return 503 with `"mesh requires AGENTMEMORY_SECRET"` if the secret is not configured
+- All 5 mesh REST endpoints (`mesh-register`, `mesh-list`, `mesh-sync`, `mesh-receive`, `mesh-export`) now return 503 with `"mesh requires AGENTMEMORY_SECRET"` if the secret is not configured📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - All 4 mesh REST endpoints (`mesh-register`, `mesh-list`, `mesh-sync`, `mesh-receive`, `mesh-export`) now return 503 with `"mesh requires AGENTMEMORY_SECRET"` if the secret is not configured | |
| - The `mem::mesh-sync` function now accepts a `meshAuthToken` parameter and **refuses to sync at all** if the token is missing | |
| - All 5 mesh REST endpoints (`mesh-register`, `mesh-list`, `mesh-sync`, `mesh-receive`, `mesh-export`) now return 503 with `"mesh requires AGENTMEMORY_SECRET"` if the secret is not configured | |
| - The `mem::mesh-sync` function now accepts a `meshAuthToken` parameter and **refuses to sync at all** if the token is missing |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/security-advisories/04-mesh-unauth.md around lines 26 - 27, The
advisory text incorrectly states "All 4 mesh REST endpoints" while listing five
endpoints (`mesh-register`, `mesh-list`, `mesh-sync`, `mesh-receive`,
`mesh-export`); update the count to "All 5 mesh REST endpoints" (or remove the
numeric count) so it matches the listed endpoints, and ensure the second bullet
referencing `mem::mesh-sync` remains accurate about the new `meshAuthToken`
parameter and refusal to sync when missing.
| Fixed in **0.8.2**: | ||
|
|
||
| - New `AGENTMEMORY_EXPORT_ROOT` environment variable (default: `~/.agentmemory`) | ||
| - `vaultDir` now goes through `resolveVaultDir()` in `src/functions/obsidian-export.ts`: | ||
| - Resolves the path with `path.resolve` | ||
| - Checks `resolved === root || resolved.startsWith(root + path.sep)` | ||
| - Returns `null` if the check fails, and the endpoint returns `{ success: false, error: "vaultDir must be inside AGENTMEMORY_EXPORT_ROOT" }` | ||
| - Default export is confined to `~/.agentmemory/vault` | ||
| - Tests added in `test/obsidian-export.test.ts` for both the custom-but-valid case and the rejection case | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify whether vaultDir containment uses symlink-aware checks and whether tests cover symlink escapes.
set -euo pipefail
echo "== Locate resolveVaultDir implementation =="
rg -n -C3 'function\s+resolveVaultDir|realpath|lstat|statSync|startsWith\(root \+ sep\)' src/functions/obsidian-export.ts
echo
echo "== Check for symlink-related test coverage =="
rg -n -C2 'symlink|realpath|vaultDir.*\.\.|outside-root|AGENTMEMORY_EXPORT_ROOT' test/obsidian-export.test.tsRepository: rohitg00/agentmemory
Length of output: 896
🏁 Script executed:
# Check the full resolveVaultDir function and surrounding context
cat -n src/functions/obsidian-export.ts | head -50
# Also check if there are any realpath or symlink-safe checks elsewhere in the file
rg -n 'realpath|statSync|lstat|readlinkSync|realpathSync' src/functions/obsidian-export.tsRepository: rohitg00/agentmemory
Length of output: 1895
🏁 Script executed:
# Check full test file to ensure no symlink-related tests exist
cat -n test/obsidian-export.test.ts | grep -A5 -B5 -i symlink
# Also check if there are any other symlink checks in the entire codebase
rg -r 'realpath|statSync.*lstat|symlink' --type js --type ts src/ test/Repository: rohitg00/agentmemory
Length of output: 19657
🏁 Script executed:
# Search directly for symlink-related keywords in the obsidian-export files
grep -r "symlink\|realpath\|lstat" src/functions/obsidian-export.ts test/obsidian-export.test.ts || echo "No matches found"
# Also check the security advisory file mentioned in the review
cat -n .github/security-advisories/05-obsidian-export-traversal.md | head -60Repository: rohitg00/agentmemory
Length of output: 3301
The mitigation for symlink-based path traversal is incomplete
The fix uses path.resolve() and a prefix check, but path.resolve() does not follow symlinks. An attacker can create a symlink inside the allowed root directory pointing outside it—e.g., ~/.agentmemory/link → /etc—and the check will pass while mkdir() and writeFile() will escape containment. The advisory should either label this as a partial mitigation or add symlink-safe checks (e.g., realpathSync() or lstat()-based validation) and corresponding test coverage.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/security-advisories/05-obsidian-export-traversal.md around lines 33
- 42, resolveVaultDir in src/functions/obsidian-export.ts currently uses
path.resolve + a prefix check which does not follow symlinks, allowing
symlink-based traversal; update resolveVaultDir to perform symlink-safe
resolution (e.g., use fs.realpathSync on the resolved path and the
AGENTMEMORY_EXPORT_ROOT, or verify with lstat to ensure no path component inside
the root is a symlink that points outside) and ensure mkdir/writeFile calls
operate on the realpath result; update tests in test/obsidian-export.test.ts to
include a symlink escape case and assert the endpoint returns the same rejection
({ success: false, error: "vaultDir must be inside AGENTMEMORY_EXPORT_ROOT" })
when a symlink inside the root points outside.
- 04-mesh-unauth.md: correct 4->5 mesh REST endpoints in patch summary. - 05-obsidian-export-traversal.md: document the known symlink-traversal limitation of resolveVaultDir(). The 0.8.2 fix uses lexical containment only (path.resolve + startsWith) and does not call realpath/lstat, so a pre-existing symlink under AGENTMEMORY_EXPORT_ROOT pointing outside the root is still a viable escape. Advisory now names this explicitly and points users at sandboxing or a follow-up issue for full hardening.
Bump version + ship CHANGELOG covering everything that merged since v0.8.13: - #118 security advisory drafts for v0.8.2 CVEs - #132 semantic eviction routing + batched retention audit - #157 iii console docs + vendored screenshots in README - #160 (#158) health gated on RSS floor - #161 (#159) standalone MCP proxies to the running server - #162 (#125) mem::forget audit coverage + policy doc - #163 (#62) @agentmemory/fs-watcher filesystem connector - #164 Next.js website (website/ root, ship to Vercel) Version bumps (8 files): - package.json / package-lock.json (top + packages['']) - plugin/.claude-plugin/plugin.json - packages/mcp/package.json (self + ~0.9.0 dep pin) - src/version.ts (union extended, assigned 0.9.0) - src/types.ts (ExportData.version union) - src/functions/export-import.ts (supportedVersions set) - test/export-import.test.ts (export assertion) Tests: 777 passing. Build clean.
Six security advisory drafts for v0.8.2, one per CVE. These are reference material for the actual GitHub Security Advisories that need to be filed through the UI at:
https://github.com/rohitg00/agentmemory/security/advisories/new
Each draft includes severity, CVSS 3.1 vector, CWE classification, affected/patched versions, impact analysis, patch description, and workarounds.
Advisories (in severity order)
All six were fixed in PR #108 (v0.8.2). This PR just commits the drafts so the information is preserved in the repo history.
Summary by CodeRabbit