Back to skill

Security audit

Memory Oracle

Security checks for vulnerabilities and agentic risk

Overview

This memory skill has a coherent purpose, but it needs Review because it stores and reuses conversations persistently with weak scoping, can promote ordinary text into always-active rules, and can send memory data to an external or configurable endpoint.

Review before installing. Use LIGHT-only mode unless you are comfortable with persistent cross-session memory and external processing of daily logs; avoid shared or group contexts until isolation is enforced; do not point api.base_url at another endpoint while using ANTHROPIC_API_KEY; avoid --force uninstall; and inspect or back up memory data before enabling cron or deletion paths.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (8)

T02 · Agent Memory Poisoning

Error
Location
config/patterns.json:81
Finding

Untrusted Conversation Text Can Become Persistent, Always-Active Agent Instructions

Content
View full analysis
Remediation
View remediation

T02 · Agent Memory Poisoning

Error
Location
scripts/reflect.py:143
Finding

LLM Responses Can Autonomously Rewrite and Poison Persistent Memory

Content
View full analysis
= SETTINGS["reflection"]["confidence_threshold"] if applied: apply_reflection(conn, result, "light") ``` ```python if fact_type == "guardrail": gid = generate_id("grd") conn.execute( "INSERT INTO guardrails (id, content, created_at, source) VALUES (?, ?, ?, 'consolidate')", (gid, content, now), ) ``` The configured threshold is: ```json "reflection": { "confidence_t ...[truncated 1844 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/consolidate.py:36
Finding

Unredacted Daily Logs and Persistent Memory Are Sent to an External LLM

Content
View full analysis
str: """Read a daily log file.""" logs_dir = os.path.expanduser(SETTINGS["paths"]["daily_logs"]) log_path = os.path.join(logs_dir, f"{target_date}.md") if not os.path.exists(log_path): return "" with open(log_path, "r", encoding="utf-8") as f: return f.read() ``` ```python payload = { "model": SETTINGS["api"]["model"], "max_tokens": SETTINGS["api"]["max_tokens"], "system": system_prompt, "messages": [{"role": "user", "content": user_content}], } ``` ```python log_text = read_daily_log(target_date) if not log_text: results["note"] = "no daily log found" else: prompt = read_prompt("consolidate.txt") llm_facts = call_claude_api(prompt, log_text) ``` Reflection additionally sends stored memory: ```python user_content = json.dumps({ "WEEK_REFLECTIONS": week_reflections, "MEMORY_FACTS": memory_facts, "FACT_ACCESS_LOG": access_log[:50], }, ensure_ascii=False) ``` ### Technical Analysis `consolidate.py` reads and submits the entire daily Markdown log rather than a minimized or prefiltered representation. `reflect.py` submits current memory facts and prior reflection data. No filtering detects API keys, authentication tokens, private keys, passwords, personal information, confidential code, health information, financial information, or other sensitive content. Possession of `ANTHROPIC_API_KEY` is treated as sufficient consent for all nightly data transmission. The system does not provide a payload preview, per-record consent, sensitivity labels, or an allowlist of fields that ...[truncated 940 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/consolidate.py:55
Finding

Configurable API Endpoint Receives the Anthropic API Key

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/recall.py:303
Finding

Private Memory Is Recalled Without User, Session, or Group-Context Isolation

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
install.sh:76
Finding

Custom Workspace and Installation Paths Permit Python or Cron Command Injection

Content
View full analysis
> /tmp/memory-oracle-cron.log 2>&1" (crontab -l 2>/dev/null || true; echo "# memory-oracle nightly pipeline"; echo "$CRON_CMD_NIGHTLY") | crontab - ``` ### Technical Analysis `WORKSPACE` and `SCRIPT_DIR` are embedded directly inside a Python program enclosed by a shell string. A path containing a single quote, newline, or Python syntax can terminate the intended string and inject arbitrary Python statements. The cron command also includes unquoted script and interpreter paths. Shell metacharacters or whitespace in those paths can change the generated command. Because the cron entry persists, injected shell content may execute later and repeatedly. Normal installation paths are generally trusted, but the installer explicitly accepts a custom workspace argument and should not transform path data into executable source. ### Attack Path 1. An attacker persuades a user or automation system ...[truncated 837 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
uninstall.sh:79
Finding

Uninstaller Can Remove Unrelated User Cron Entries

Content
View full analysis
/dev/null | grep -c "memory-oracle" || true) if [[ "$CRON_COUNT" -gt 0 ]]; then if [[ "$FORCE" == "true" ]]; then CONFIRM="y" else warn "Found $CRON_COUNT memory-oracle cron job(s)." read -r -p "Remove them? [Y/n] " CONFIRM CONFIRM="${CONFIRM:-y}" fi if [[ "$CONFIRM" =~ ^[Yy]$ ]]; then crontab -l 2>/dev/null | grep -v "memory-oracle" | crontab - info " Cron jobs removed." fi fi ``` ### Technical Analysis Cron ownership is determined by a substring search. Removal discards every line containing `memory-oracle`, not only the exact entry installed by this project. The confirmation reports all matching lines as Memory Oracle jobs even when some may belong to unrelated scripts, comments, paths, or commands. The `--force` option performs this modification without interactive review. ### Attack Path 1. The user has another cron entry whose command, path, or comment contains the string `memory-oracle`. 2. The user runs `uninstall.sh` and approves removal, or runs it with `--force`. 3. `grep -v "memory-oracle"` removes both the managed entry and every unrelated matching line. 4. The filtered crontab replaces the original crontab. 5. Unrelated scheduled work no longer executes. ### Impact Assessment The vulnerability can cause denial of service or loss of automation for the affected user account. It cannot directly execute attacker code, but it can disable backups, monitoring, maintenance, or other scheduled jobs containing the matching substring. ]]>
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/maintenance.py:88
Finding

Configuration-Key Mismatch Aborts the Nightly Maintenance Pipeline

Content
View full analysis
dict: """Delete facts below delete threshold that are old enough.""" threshold = SETTINGS["scoring"]["delete_threshold"] min_age = SETTINGS["maintenance"]["delete_min_age_days"] cutoff_date = (utcnow() - timedelta(days=min_age)).isoformat() ``` The referenced value is actually defined under `scoring`: ```json "scoring": { "archive_threshold": 0.2, "delete_threshold": 0.05, "delete_min_age_days": 90 } ``` The cron task chains maintenance after the other operations: ```bash $PYTHON scripts/consolidate.py && $PYTHON scripts/reflect.py --auto && $PYTHON scripts/maintenance.py ``` ### Technical Analysis `prune_dead()` looks up `delete_min_age_days` in the `maintenance` object, but the supplied configuration defines the key in `scoring`. A normal full maintenance cycle therefore raises `KeyError` when it reaches pruning. Within `maintenance.py`, later log cleanup, `MEMORY.md` rendering, and database vacuuming do not run after the exception. This undermines the documented retention and self-maintenance behavior. ### Attack Path 1. The user installs the project with its supplied configuration. 2. The nightly task invokes `maintenance.py`. 3. `apply_decay()` and `archive_cold()` may run. 4. `prune_dead()` accesses the nonexistent configuration key. 5. Python raises `KeyError` and terminates the process. 6. Pruning, old-log deletion, memory rendering, and vacuuming are skipped. 7. The same failure repeats on later nightly runs until configuration or code is corrected. ### Impact Assessment The direct impact is availability and retention-policy failure. Stale records and daily logs can remain longer than documented, potentially in ...[truncated 160 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (48)

Tainted flow: 'req' from os.environ.get (line 70, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/consolidate.py (reported line 82)May include surrounding context.

python
)

    try:
        with urllib.request.urlopen(req, timeout=SETTINGS["api"]["timeout_seconds"]) as resp:
            data = json.loads(resp.read().decode("utf-8"))
            text = ""
            for block in data.get("content", []):

Tainted flow: 'req' from os.environ.get (line 60, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/reflect.py (reported line 72)May include surrounding context.

python
)

    try:
        with urllib.request.urlopen(req, timeout=SETTINGS["api"]["timeout_seconds"]) as resp:
            data = json.loads(resp.read().decode("utf-8"))
            text = ""
            for block in data.get("content", []):

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill is presented as a memory utility, but the documented uninstall/rollback behavior includes crontab modification, database/workspace deletion, and restoration of MEMORY.md. That functional breadth increases risk because users or agents may invoke a seemingly simple memory skill without appreciating that it can alter scheduled tasks and remove local state.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill is presented as a memory utility, but the documented uninstall/rollback behavior includes crontab modification, database/workspace deletion, and restoration of MEMORY.md. That functional breadth increases risk because users or agents may invoke a seemingly simple memory skill without appreciating that it can alter scheduled tasks and remove local state.

Content

No source excerpt is available for this finding.

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · uninstall.sh (reported line 147)May include surrounding context.

sh
# 5. Clean up ancillary files
for F in "${WORKSPACE}/memory-oracle-pending.json"; do
    [[ -f "$F" ]] && rm -f "$F" && info "  Removed: $F"
done

# Clean reflection files

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · uninstall.sh (reported line 160)May include surrounding context.

sh
# 5. Clean up ancillary files
for F in "${WORKSPACE}/memory-oracle-pending.json"; do
    [[ -f "$F" ]] && rm -f "$F" && info "  Removed: $F"
done

# Clean reflection files

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · uninstall.sh (reported line 161)May include surrounding context.

sh
# 5. Clean up ancillary files
for F in "${WORKSPACE}/memory-oracle-pending.json"; do
    [[ -f "$F" ]] && rm -f "$F" && info "  Removed: $F"
done

# Clean reflection files

Self-Modification

High
Category
Rogue Agent
Confidence
70% confidence
Finding

Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Content

Scanner excerpt · uninstall.sh (reported line 172)May include surrounding context.

sh
info ""
info "Manual steps remaining:"
info "  1. Remove the Memory Oracle Protocol section from your AGENTS.md"
info "  2. Remove the checkpoint.py reference from your compaction config"
info "  3. Optionally: rm -rf $SCRIPT_DIR  (remove skill files)"
info ""
if [[ -f "${WORKSPACE}/memory-oracle-export-"* ]] 2>/dev/null; then

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill documents substantial capabilities—filesystem reads/writes, environment-variable access, cron manipulation, and optional network calls—without any explicit tool/permission scope. In an agent ecosystem, missing scope declarations weaken reviewability and can let a broadly-triggered memory skill execute higher-impact operations than a user would reasonably expect.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger phrases are very broad ('memory', 'remember', 'recall', 'guardrails', 'pick up where we left off'), making accidental invocation likely in ordinary conversation. Because the skill stores and retrieves persistent context, unintended activation can cause over-collection, unnecessary retention, or disclosure of prior-session information in contexts where the user did not explicitly ask for persistence.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill is explicitly designed to preserve facts across sessions and to answer 'what do you know about X' from stored memory. In a memory skill this is contextually expected, but without strong consent boundaries and scoping it still creates a real risk of retaining and later disclosing personal or sensitive information beyond the user's intent.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The protocol instructs the agent to persist the full conversation turn after every response and to feed user queries into recall processing. That creates a strong data-retention pathway for potentially sensitive user content, and the same memory may later be surfaced or transmitted to HEAVY reflection/consolidation flows, increasing privacy and confidentiality risk across sessions.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

The documented use of '--force' to skip confirmations for uninstall operations is risky because the same uninstall flow includes cron removal, cleanup of files, optional database deletion, and restoration actions. In agent-driven environments, non-interactive destructive modes can be triggered without adequate human review, increasing the chance of accidental data loss or system modification.

Content

Scanner excerpt · SKILL.md (reported line 147)May include surrounding context.

md
5. Clean up reflection files and pending queue
6. Print remaining manual steps (AGENTS.md cleanup, compaction config)

Use `--force` to skip confirmations, `--keep-db` to keep the database while removing everything else.

## Known issues & limitations

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documentation first says that if the API key is not set, the HEAVY process is skipped entirely, but immediately afterward says users can point api.model to a local model endpoint instead. Those statements cannot both be universally true, so the docs actively contradict the described behavior and deployment options.

Content

No source excerpt is available for this finding.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The file defines parallel patterns_en and patterns_ru matchers throughout the configuration, indicating the skill is designed to operate only for English and Russian inputs. Because no natural-language text in this file offers user opt-in or explains a justified region-specific limitation, this creates a locale policy concern under the language/locale rule.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · config/settings.json (reported line 62)May include surrounding context.

json
"api": {
    "model": "claude-sonnet-4-20250514",
    "max_tokens": 1000,
    "base_url": "https://api.anthropic.com/v1/messages",
    "timeout_seconds": 30
  },
  "cron": {

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · install.sh (reported line 67)May include surrounding context.

sh
error "FTS5 is required for full-text search."
    error ""
    error "How to fix:"
    error "  Ubuntu/Debian: sudo apt install libsqlite3-dev && rebuild Python"
    error "  Alpine:        apk add sqlite-dev"
    error "  macOS:         brew install sqlite3 (FTS5 included by default)"
    error "  Or use pyenv:  PYTHON_CONFIGURE_OPTS='--enable-loadable-sqlite-extensions' pyenv install 3.12"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

When --workspace is provided, the script silently updates config/settings.json in place, changing multiple path settings. Although it logs the custom workspace, it does not clearly disclose that a tracked configuration file will be modified before performing the write.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

The installer offers to add a persistent nightly cron job that will continue executing the skill's Python scripts across sessions. In the context of a memory skill that processes stored conversational data and may use an API key, persistence increases risk by enabling ongoing unattended access to user data and repeated execution long after the original install decision.

Content

Scanner excerpt · install.sh (reported line 138)May include surrounding context.

sh
CRON_CMD_NIGHTLY="0 3 * * * cd $SCRIPT_DIR && ANTHROPIC_API_KEY=\${ANTHROPIC_API_KEY} $PYTHON scripts/consolidate.py && $PYTHON scripts/reflect.py --auto && $PYTHON scripts/maintenance.py >> /tmp/memory-oracle-cron.log 2>&1"

        # Check if already installed
        EXISTING=$(crontab -l 2>/dev/null | grep -c "memory-oracle" || true)
        if [[ "$EXISTING" -gt 0 ]]; then
            warn "Cron jobs already exist. Skipping. To reinstall, remove them first:"
            warn "  crontab -e  # then remove memory-oracle lines"

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · install.sh (reported line 141)May include surrounding context.

sh
EXISTING=$(crontab -l 2>/dev/null | grep -c "memory-oracle" || true)
        if [[ "$EXISTING" -gt 0 ]]; then
            warn "Cron jobs already exist. Skipping. To reinstall, remove them first:"
            warn "  crontab -e  # then remove memory-oracle lines"
        else
            (crontab -l 2>/dev/null || true; echo "# memory-oracle nightly pipeline"; echo "$CRON_CMD_NIGHTLY") | crontab -
            info "Cron installed: nightly at 03:00"

Session Persistence

Medium
Category
Rogue Agent
Confidence
94% confidence
Finding

This command actually installs a cron entry into the user's crontab, establishing durable background execution. Within this skill's context, that is more security-relevant than ordinary automation because the scheduled jobs process persistent memory, may invoke LLM-backed reflection using ANTHROPIC_API_KEY, and write logs to /tmp, increasing exposure if the behavior is not fully understood by the user.

Content

Scanner excerpt · install.sh (reported line 143)May include surrounding context.

sh
warn "Cron jobs already exist. Skipping. To reinstall, remove them first:"
            warn "  crontab -e  # then remove memory-oracle lines"
        else
            (crontab -l 2>/dev/null || true; echo "# memory-oracle nightly pipeline"; echo "$CRON_CMD_NIGHTLY") | crontab -
            info "Cron installed: nightly at 03:00"
        fi
    else

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The printed AGENTS.md snippet instructs activation based on the exact English phrases "remember this" or "this is critical." This hard-codes an English-only interaction pattern without user opt-in or any documented locale flexibility.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The prompt instructs the model to write the strategic summary in the user's primary language at L58 and repeats the requirement at L69. This imposes a language behavior without indicating that the user selected or consented to that locale choice, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The prompt instructs the model to write the daily summary in the language it infers the user primarily uses, without requiring an explicit user preference or current-session consent. In a persistent memory system, this can cause unexpected disclosure, misclassification of language preference, or generation of summaries in a language unsuitable for downstream reviewers or safety workflows.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.