Skip to the content.

mnemosyne-oss/mnemosyne - security scan

Repository: mnemosyne-oss/mnemosyne Commit scanned: 2812e98b986688339a1cd489f1e4999a30d52171 Scan date: 2026-07-15 Disclosure status: public — post-only (strict-norm: SECURITY.md + sync infrastructure; nothing cleared the quality gate)

Summary

Severity Count
Critical 0
High 128
Medium 67
Low 0 (filtered at --min-severity medium)
Info 0

Total findings: 195 (0 real after curation)

Mnemosyne is a zero-dependency, SQLite-backed AI memory system with an MCP server and an end-to-end-encrypted sync server. “Zero-dependency” means the security surface is its own code — a lot of hand-written SQL over sqlite3 — and that shows in the numbers: 140 of the 195 findings are one SQL cluster, the largest in the series. It’s also the cleanest kind of large cluster, because the SQL is correctly parameterized; the 128 highs dissolve on inspection.

Top findings

1. The 140-finding SQL cluster is parameterized data + internal identifiers

2. Outbound fetches are user-directed imports and own-server sync

3. The “secrets” are documentation and the crypto is thoughtful

Patterns observed

The largest SQL cluster in the series, and it evaporates on one query read. 128 highs sounds like a five-alarm SQL-injection fire on a store that holds user text. But the discriminator is always the same: are values bound, and are the interpolated tokens identifiers or data? Here values are ?-bound (with LIKE escaping), and the f-string tokens are internal table/column names and constant embedding dimensions. Reading two representative queries — a recall SELECT and a CREATE VIRTUAL TABLE — settled all 140. The scanner can’t see the parameter tuple one argument over; a human can in a minute.

Zero-dependency shifts the surface to SQL, and they handled it. Most scans in this series split between code findings and a dependency tail. A zero-dependency project has almost no tail (trivy found 6, all minor), so the whole scan is the hand-written data layer — and mnemosyne writes it carefully, down to ESCAPE clauses on LIKE and identifier branches that never touch request input.

Strict-norm, security-conscious, clean. A real SECURITY.md, a sync server with client-side encryption, and JWT auth put this firmly in post-only territory — and there was nothing to file. The 195-count is one parameterized SQL cluster, operator-directed fetches, docs keys, and docker-compose hardening lint.

Notes on the tool

Disclosure timeline

This is a post-only clean-scan write-up. The 140-finding SQL cluster is parameterized data with internal identifiers (LIKE-escaped), the outbound fetches are operator-directed imports and sync, the secret hits are documentation, dependencies are negligible, and the sync layer is client-side encrypted. Nothing cleared the quality gate.

Reproduce

git clone https://github.com/mnemosyne-oss/mnemosyne /tmp/scan-target
python scanner/run_scan.py --repo /tmp/scan-target \
  --reports-dir ./reports/mnemosyne-oss-mnemosyne \
  --min-severity medium --ignore-samples