Security Audit Report — memory-bank-skill Repository¶
Archived historical snapshot. This audit predates the 4.x/5.x releases; the key findings (uninstall path validation, manifest handling,
metrics.shoverride execution) were addressed afterwards — see SECURITY.md § Known security-relevant design decisions. Kept for transparency and regression context.
Audit Date: 2026-04-21
Scope: Full repository (/Users/fockus/Apps/claude-skill-memory-bank)
Files Reviewed: 45+ shell scripts, Python modules, adapters, hooks, and configuration files
Auditor: OpenCode Security Review
Executive Summary¶
The memory-bank-skill repository is a well-structured dev-toolkit with generally good security hygiene. No Critical vulnerabilities were identified. However, two High-severity and six Medium-severity issues were found, primarily related to:
- Path traversal in uninstall logic and
.claude-workspaceresolution - Manifest poisoning enabling arbitrary file deletion
- Arbitrary code execution via intentional but unvalidated override mechanisms
- Backup retention leaks of potentially sensitive migration data
The codebase demonstrates positive patterns: atomic file writes in Python, PII redaction for search/indexing, dangerous-command blocking hooks, and absence of hardcoded secrets.
Findings Summary¶
| # | Severity | Category | File | Description |
|---|---|---|---|---|
| 1 | High | Path Traversal | uninstall.sh |
Manifest-based rm -rf bypasses prefix validation with traversal sequences |
| 2 | High | Path Traversal | scripts/_lib.sh |
.claude-workspace project_id is unsanitized, redirecting all MB ops |
| 3 | High | Arbitrary File Deletion | adapters/pi.sh |
uninstall_skill_mode runs rm -rf on manifest-controlled path |
| 4 | Medium | Symlink Attack | install.sh |
backup_if_exists follows symlinks, enabling arbitrary overwrites |
| 5 | Medium | Arbitrary Code Execution | scripts/mb-metrics.sh |
Auto-executes .memory-bank/metrics.sh if present |
| 6 | Medium | Data Exposure | hooks/file-change-log.sh |
File paths logged to predictable location; racy rotation |
| 7 | Medium | Sensitive Data Retention | scripts/mb-import.py |
JSONL transcripts may contain secrets beyond PII regex scope |
| 8 | Medium | Backup Leak | scripts/mb-migrate-structure.sh |
Migration backups in .pre-migrate/ never auto-purged |
| 9 | Low | Race Condition | hooks/file-change-log.sh |
Non-atomic log rotation may lose/corrupt entries |
| 10 | Low | Backup Leak | adapters/git-hooks-fallback.sh |
Hook backups persist in .git/hooks/ if uninstall skipped |
Detailed Findings¶
1. HIGH — uninstall.sh Path Traversal via Manifest Poisoning¶
- File:
uninstall.sh - Lines: 32–63
- Severity: High
- Description:
The uninstaller reads file paths from
.installed-manifest.jsonand performs prefix checks: Bashcaseprefix matching is vulnerable to directory traversal sequences embedded in the path. A manifest entry like: starts with/home/user/.claude/and therefore passes the prefix check, causingrm -rf /etc/passwdto execute. - Exploit Scenario:
An attacker with write access to
.installed-manifest.json(or who tricks the user into installing from a poisoned manifest) can delete arbitrary files or directories owned by the user. - Recommendation: Resolve and canonicalize paths before validation: Additionally, verify the resolved path is still within the expected directory subtree.
2. HIGH — scripts/_lib.sh Path Traversal via .claude-workspace¶
- File:
scripts/_lib.sh - Lines: 12–31
- Severity: High
- Description:
The
mb_resolve_path()helper readsproject_idfrom.claude-workspacewithout sanitization:A maliciousproject_id=$(grep '^project_id:' .claude-workspace 2>/dev/null | awk '{print $2}' | tr -d '"' || true) if [ -n "$project_id" ]; then printf '%s\n' "$HOME/.claude/workspaces/$project_id/.memory-bank".claude-workspacefile in the working directory (e.g.,project_id: ../../../etc) redirects all memory-bank scripts (mb-note.sh,mb-compact.sh,mb-search.sh, etc.) to operate outside the intended directory. - Exploit Scenario:
An attacker places a crafted
.claude-workspacein a shared project. When the victim runsmb-note.sh "foo", the note is written to/etc/.memory-bank/notes/...(if writable), ormb-compact.sh --applyarchives files from arbitrary locations and deletes them. - Recommendation:
Sanitize
project_idto allow only[a-zA-Z0-9_-]+: Additionally, resolve the final path and verify it resides under$HOME/.claude/workspaces/.
3. HIGH — adapters/pi.sh Arbitrary File Deletion via Manifest¶
- File:
adapters/pi.sh - Lines: 88–96
- Severity: High
- Description:
The
uninstall_skill_modefunction readspi_skill_dirfrom.mb-pi-manifest.jsonand executesrm -rfwithout validation:If the manifest is tampered with (e.g.,skill_path=$(jq -r '.pi_skill_dir' "$MANIFEST") [ -n "$skill_path" ] && [ -d "$skill_path" ] && rm -rf "$skill_path""pi_skill_dir": "/home/user"), the uninstaller recursively deletes the user's home directory. - Exploit Scenario: A malicious manifest placed before uninstall causes catastrophic data loss.
- Recommendation:
Validate that
skill_pathis exactly~/.pi/agent/skills/memory-bankor resolve and verify it is a subdirectory of~/.pi/agent/skills/.
4. MEDIUM — install.sh Symlink Attack in backup_if_exists¶
- File:
install.sh - Lines: 287–312
- Severity: Medium
- Description:
backup_if_existschecks if a target exists and moves it to a backup path: If$targetis a symlink pointing to a sensitive file (e.g.,~/.ssh/config),mvmoves the symlink itself. The subsequentcp "$src" "$dst"writes the new content to the symlink destination, overwriting the sensitive file. - Exploit Scenario:
An attacker with pre-existing symlink control in
~/.claude/can redirect installer output to overwrite arbitrary files. - Recommendation:
Use
cp -Lorreadlink -fto detect symlinks, and refuse to overwrite targets that are symlinks pointing outside the managed directory tree.
5. MEDIUM — scripts/mb-metrics.sh Arbitrary Code Execution Override¶
- File:
scripts/mb-metrics.sh - Lines: 28–31
- Severity: Medium
- Description:
The script auto-detects a project-specific metrics override and executes it unconditionally:
While this is an intentional extension point, a malicious
.memory-bank/metrics.shin a cloned repository will execute arbitrary shell code when the victim runsmb-metrics.sh. - Exploit Scenario:
A cloned repository contains a malicious
.memory-bank/metrics.sh. The victim runs the memory-bank workflow, triggering code execution. - Recommendation:
Require an explicit opt-in (e.g.,
MB_ALLOW_METRICS_OVERRIDE=1) before executing user-provided override scripts. Document the security implication clearly.
6. MEDIUM — hooks/file-change-log.sh Path Disclosure & Racy Rotation¶
- File:
hooks/file-change-log.sh - Lines: 21, 24–40
- Severity: Medium
- Description:
- Path disclosure: File change events are logged to a predictable path
$HOME/.claude/file-changes.log, including paths to files the user may consider sensitive. - Race condition: Log rotation is non-atomic: Two concurrent hook invocations can interleave between size check and rotation, causing log loss or corruption.
- Exploit Scenario:
An attacker with read access to the user's home directory can inspect
file-changes.logto reconstruct the project's file structure and naming conventions. Concurrent tool use may corrupt logs. - Recommendation:
- Set restrictive permissions on the log file (
chmod 600). - Use atomic rotation (e.g.,
ln+mvpattern, or append with size checking in a single process).
7. MEDIUM — scripts/mb-import.py Sensitive Data Retention¶
- File:
scripts/mb-import.py - Lines: 186–298
- Severity: Medium
- Description:
The importer reads Claude Code JSONL session transcripts and extracts content into
.memory-bank/notes/andprogress.md. While it redacts emails and API keys via regex, it does not redact: - Passwords or authentication tokens in conversation text
- Proprietary business logic or architecture details
- Personal Identifiable Information (PII) beyond email addresses
- The redaction regex itself may miss API key formats not covered by the hardcoded patterns.
- Exploit Scenario:
A developer pastes a database password or proprietary algorithm into a Claude Code session. Later,
mb-import.py --applywrites this to.memory-bank/notes/, where it may be committed to git or shared. - Recommendation:
- Expand
APIKEY_REto cover additional patterns (e.g.,AKIA...for AWS,glpat-...for GitLab). - Add a generic secret detector (e.g.,
detect-secretsorgit-secretsstyle entropy check). - Document that
--applymay retain sensitive conversational data and recommend reviewing imported notes before committing.
8. MEDIUM — scripts/mb-migrate-structure.sh Backup Retention Leak¶
- File:
scripts/mb-migrate-structure.sh - Lines: 81–86
- Severity: Medium
- Description:
The migrator creates timestamped backups:
These backups are never automatically cleaned up. Over time,
backup_dir="$MB_PATH/.pre-migrate/$timestamp" mkdir -p "$backup_dir" for f in plan.md STATUS.md BACKLOG.md checklist.md; do [ -f "$MB_PATH/$f" ] && cp "$MB_PATH/$f" "$backup_dir/".pre-migrate/accumulates historical versions of files that may contain sensitive plans, architecture decisions, or security review findings. - Exploit Scenario:
A repository containing
.memory-bank/is shared or published. Old backups in.pre-migrate/leak deprecated but sensitive content that the user believed was removed. - Recommendation:
- Document backup retention and advise users to periodically clean
.pre-migrate/. - Optionally, cap retention (e.g., keep only the last 3 backups) or exclude
.pre-migrate/from git via.gitignore.
9. LOW — hooks/file-change-log.sh Race Condition in Rotation¶
- File:
hooks/file-change-log.sh - Lines: 24–34
- Severity: Low
- Description: Same as finding #6, but focused on the race condition alone. The size-check-then-move pattern is a classic TOCTOU race. Impact is limited to log integrity.
- Recommendation:
Implement atomic rotation using
lnandmvswap, or use a logrotate wrapper.
10. LOW — adapters/git-hooks-fallback.sh Backup Leak¶
- File:
adapters/git-hooks-fallback.sh - Lines: 151–159, 210–222
- Severity: Low
- Description:
During install, existing git hooks are backed up as
post-commit.pre-mb-backup. During uninstall, they are restored. If uninstall is never run or fails, these backup files remain in.git/hooks/, potentially leaking the contents of the original hooks (which may contain custom logic or secrets). - Exploit Scenario:
A user installs the adapter, then switches to a different tool without running uninstall. The
.git/hooks/*.pre-mb-backupfiles persist and may be committed if the user mistakenly stages them. - Recommendation:
Add
.pre-mb-backupto.gitignoreduring install, or store backups outside.git/hooks/(e.g., in.git/mb-backups/).
Positive Security Practices Observed¶
| Practice | Where Observed |
|---|---|
| Atomic file writes | settings/merge-hooks.py, scripts/mb-import.py, scripts/mb-index-json.py, scripts/mb-codegraph.py all use tempfile.mkstemp() + os.replace() |
| PII redaction | scripts/mb-search.sh strips <private> blocks by default; mb-index-json.py excludes them from indexing |
| Dangerous command blocking | hooks/block-dangerous.sh blocks rm -rf /, DROP TABLE, force-push, curl pipe-to-shell, etc. |
| No hardcoded secrets | No API keys, tokens, or passwords found in any source file |
| Safe subprocess usage | memory_bank_skill/cli.py uses subprocess.run() with list arguments (no shell=True) |
| Input validation | mb-plan.sh sanitizes topics via mb_sanitize_topic() to [a-z0-9-] |
| Safe jq usage | All jq invocations use --arg / --argjson, preventing injection |
| No eval/exec | No eval, exec, or source of user-controlled data found in Python or shell scripts |
| Trusted Publishing | .github/workflows/publish.yml uses PyPI OIDC instead of long-lived API tokens |
Recommendations Summary¶
- Immediately fix the path traversal in
uninstall.shby canonicalizing paths before prefix validation. - Immediately sanitize
project_idinscripts/_lib.shto prevent.claude-workspacetraversal. - Immediately validate
pi_skill_dirinadapters/pi.shbeforerm -rf. - Short-term require explicit opt-in (
MB_ALLOW_METRICS_OVERRIDE=1) formetrics.shexecution. - Short-term detect and refuse to follow symlinks in
install.shbackup logic. - Medium-term expand secret detection patterns in
mb-import.pyand document data retention risks. - Medium-term implement automatic cleanup or
.gitignorefor migration backups inmb-migrate-structure.sh. - Ongoing run
shellcheckandbanditin CI to catch unsafe patterns.
End of Report