ESL

Security Advisory

Claude-Mem: Unauthenticated
Local Memory API Exposure

⚠ OVERALL RISK: HIGH

Comprehensive Code Review of thedotmack/claude-mem

GitHub Issue #1251 · Opened Feb 26, 2026 by CheswickDEV · Rated HIGH risk

ESL Analysis & Patch · April 2026

What is claude-mem?

A third-party persistent memory plugin for Claude Code that captures, compresses, and reinjects session context across coding sessions.

🧠 Memory Layer

Captures tool outputs, user prompts, code changes, and AI summaries. Stores them as searchable "observations" in SQLite + ChromaDB.

🔌 MCP Server

Exposes tools via Model Context Protocol: search, timeline, smart_unfold, smart_outline, smart_search, and corpus management.

🌐 Worker Daemon

Long-running Express HTTP API on port 37777 (bound to 127.0.0.1 by default). Handles data persistence, AI compression, and background processing.

📊 Scale

62K+ GitHub stars · 5.2K forks · 2000+ commits · Single maintainer · AGPL-3.0 licensed · npm: v12.2.0

History & Timeline

2024 – Early 2025
claude-mem created by Alex Newman (thedotmack). Grows rapidly with Claude Code adoption.
Dec 15, 2025
Issue #324 — Worker fails to start on port 37777 on Windows. Reveals TOCTOU race conditions in startup.
Early 2026
Issue #737 — Users report 155 zombie processes / 51 GB RAM. Claude subprocesses not terminated properly.
Feb 18, 2026
ProcessRegistry fix — Orphan reaper, SIGKILL escalation, hard cap of 10 processes added.
Feb 26, 2026
Issue #1251CheswickDEV opens comprehensive security audit. Rates project HIGH risk. Identifies 4 Critical/High, 6 Medium, 7 Low findings.
Mar 16, 2026
Process Supervisor added for unified lifecycle management (#1370).
v12.1.0
CorpusStore path traversal prevention — Proper alphanumeric validation + startsWith containment. But NOT applied to smart_unfold / smart_outline.
Apr 18, 2026
v12.2.0 released — Path traversal in MCP tools still unpatched. No auth added to HTTP API. DataCamp confirms issues "remain open."

Audit Findings Overview

From Issue #1251 — 17 findings across Critical, Medium, and Low severity

IDFindingSeverityCWEStatus
C-1Path Traversal in smart_unfold / smart_outlineCRITICALCWE-22OPEN
C-2Entire HTTP API has no authenticationHIGHOPEN
C-3Network exposure when host set to 0.0.0.0HIGHCWE-668OPEN
C-4API keys exposed via GET /api/settingsHIGHCWE-200OPEN
M-1Credential files written without restrictive permissionsMEDIUMCWE-732OPEN
M-2Auto-install via curl | bash (no checksum)MEDIUMCWE-494OPEN
M-4JSON body limit of 50 MB (memory exhaustion)MEDIUMCWE-400OPEN
M-5Error handler leaks internal detailsMEDIUMCWE-209OPEN
+ 7 Low/Informational findings (no rate limiting, ReDoS, health endpoint info leak, etc.)

What's Been Fixed So Far

Zombie Process Accumulation

Issue #737 — ProcessRegistry with PID capture, orphan reaper (every 30s), stale session reaper (every 2min), hard cap of 10 processes, SIGKILL escalation after 5s timeout.

Commit 5d79bb7 (Feb 18) + 80a8c90 (Mar 16)

CorpusStore Path Traversal

Proper two-layer defense added: alphanumeric regex allowlist + startsWith containment check after resolve(). But only for CorpusStore — not MCP tools.

CHANGELOG v12.1.0

Admin Endpoint Protection

requireLocalhost middleware added to /api/admin/restart, /api/admin/shutdown, /api/admin/doctor — IP-based guard.

CORS Localhost Restriction

CORS policy restricts browser origins to localhost / 127.0.0.1 only. Does NOT block curl, scripts, or local malware.

While these mitigations are welcome, the most critical findings from the audit remain open ↓

What's Still Open

🔴 C-1: Path Traversal

smart_unfold and smart_outline accept any file path. A compromised MCP session can read /etc/passwd, ~/.ssh/id_rsa, or any file on disk.

CWE-22 · UNPATCHED

🔴 C-2: No API Authentication

Zero bearer token, API key, or session auth on any non-admin endpoint. Any local process can exfiltrate all observations, inject false memories, or extract API keys.

UNPATCHED

🔴 C-4: Cleartext API Keys

GET /api/settings returns Gemini, OpenRouter, and Anthropic API keys in cleartext. Combined with C-2, any local process can steal them.

CWE-200 · UNPATCHED

🟡 Supply-Chain Risk

Single maintainer · curl | bash install · 2fa: false on npm · pre-1.0 SDK dependency · No SBOM · AI-modified code incident (v12.1.4)

STRUCTURAL

C-1 Deep Dive: Path Traversal

Both smart_unfold and smart_outline resolve the path but never check boundaries:

// src/servers/mcp-server.ts — VULNERABLE CODE

handler: async (args) => {
  const filePath = resolve(args.file_path);       // ← normalizes, does NOT restrict
  const content = await readFile(filePath, 'utf-8'); // ← reads ANY file on disk
  const unfolded = unfoldSymbol(content, filePath, args.symbol_name);
  // ...
}

Meanwhile, CorpusStore in the same project does it correctly:

// CorpusStore.getFilePath() — PROPERLY GUARDED

private getFilePath(name: string): string {
  const safeName = this.validateCorpusName(name);    // ← regex allowlist
  const resolved = path.resolve(this.corporaDir, safeName);
  if (!resolved.startsWith(path.resolve(this.corporaDir) + path.sep)) {
    throw new Error('Invalid corpus name');           // ← containment check
  }
  return resolved;
}

Risk Scenarios

💀 Scenario 1: Prompt Injection

A malicious repo contains a crafted comment that tricks Claude into calling smart_unfold(file_path="~/.ssh/id_rsa"). Private keys are returned in the response and may be exfiltrated via subsequent tool calls.

🕵️ Scenario 2: Local Process Espionage

Malware or a rogue npm package calls http://127.0.0.1:37777/api/settings to steal API keys, then /api/search to exfiltrate all stored observations — code, decisions, business logic.

🧪 Scenario 3: Memory Poisoning

An attacker POSTs fake observations via the unauthenticated API. Claude trusts injected "memories" in future sessions, potentially introducing backdoors or wrong decisions.

🌐 Scenario 4: Network Exposure

Developer sets CLAUDE_MEM_WORKER_HOST=0.0.0.0 for Docker. The entire API is now on the network. On shared WiFi or corporate LAN, anyone can access all data.

DataCamp (Mar 30, 2026): "claude-mem should be treated as unsafe on shared machines, cloud VMs, or environments with secrets."

ESL Security Patch

Engineering Software Lab — creator of AI security tools — has developed and published a local patch that mitigates the path traversal vulnerability (C-1).

// ESL Patch: Path containment guard injected before readFile()

handler: async (args) => {
  const filePath = resolve(args.file_path);
+ const cwd = resolve(process.cwd());
+ if (!filePath.startsWith(cwd + sep) && filePath !== cwd) {
+   throw new Error("Path traversal blocked: " + filePath + " is outside " + cwd);
+ }
  const content = await readFile(filePath, 'utf-8');
  // ... rest of handler unchanged
}

Applied to both smart_unfold and smart_outline handlers in the compiled mcp-server.cjs

📤 Upstream PR submitted: ESL has submitted a pull request to thedotmack/claude-mem to fix this in the TypeScript source (src/servers/mcp-server.ts). Until merged, use the local patch below.

How to Apply the Fix

🪟 Windows (PowerShell)

git clone https://github.com/
  zuwasi/claude-mem-security-fix

cd claude-mem-security-fix

.\apply_patch.ps1

🍎 macOS / Linux

git clone https://github.com/
  zuwasi/claude-mem-security-fix

cd claude-mem-security-fix

chmod +x apply_patch.sh
./apply_patch.sh

⚠️ Important Notes

• The patch is overwritten on plugin updates — re-run after npm update -g claude-mem
• Restart Claude Code after applying for the fix to take effect
• Run .\verify_patch.ps1 or ./verify_patch.sh to confirm 2 guards are present
• This fixes C-1 (path traversal) only — C-2/C-4 require upstream changes

Verify the Patch

# PowerShell — should return 2 matches
Select-String "Path traversal blocked" `
  "$env:APPDATA\npm\node_modules\claude-mem\plugin\scripts\mcp-server.cjs"

# Expected output:
mcp-server.cjs:217: ... Path traversal blocked ...  (smart_unfold)
mcp-server.cjs:221: ... Path traversal blocked ...  (smart_outline)

What happens after patching:

smart_unfold("./src/index.ts", "main")✓ Allowed — within project
smart_unfold("/etc/passwd", "x")✗ Blocked — outside cwd
smart_outline("../../.ssh/id_rsa")✗ Blocked — path traversal
smart_outline("./lib/utils.py")✓ Allowed — within project

Recommendations

🚨 Immediate (Do Now)

1. Apply ESL path traversal patch
2. Never set CLAUDE_MEM_WORKER_HOST=0.0.0.0
3. Don't run claude-mem on machines with production secrets or customer data
4. Pin your claude-mem version after patching

🔒 Short-Term

1. Add Windows Firewall rule blocking port 37777 inbound
2. Audit ~/.claude-mem/settings.json for exposed API keys
3. Run verify_patch.ps1 after each plugin update
4. Consider containerizing claude-mem for isolation

✅ Long-Term

1. Evaluate if you need claude-mem at all (Amp Code provides built-in threads and context)
2. Wait for upstream to add API authentication (C-2)
3. Monitor Issue #1251 for official security response
4. Consider alternative memory solutions

Engineering Software Lab

Creator of AI security tools — protecting teams from emerging AI supply-chain threats

📦 Get the ESL Security Patch

github.com/zuwasi/claude-mem-security-fix

Automated patch scripts for Windows & macOS/Linux · Verification tools · Full vulnerability report

AI Security SBOM Analysis Vulnerability Research Supply-Chain Protection

📬 Contact ESL

eswlab.com/contact-us

Original audit: CheswickDEV · Issue #1251 · Feb 26, 2026
ESL patch & advisory: April 2026

← Swipe to navigate →