Back to skill

Security audit

Agent Memory Tools

Security checks for vulnerabilities and agentic risk

Overview

This memory skill is purpose-aligned but needs review because it can automatically index workspace files, persist plaintext memory data, use optional cloud backends despite local-only claims, and run an unverified installer.

Install only if you are comfortable with a workspace memory tool that reads Markdown files, stores derived memory and raw chunks locally, and may use cloud providers if configured. Avoid running setup.sh as root, install Ollama and QMD through trusted pinned channels, keep Convex/OpenAI/OpenRouter disabled unless you explicitly want remote processing, and review or limit watch/scheduled ingestion paths before enabling background operation.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
Findings (5)

T03 · Remote Payload Retrieval and Execution

Error
Location
setup.sh:39
Finding

Unverified Remote Installer Is Downloaded and Executed Directly

Content
View full analysis
Remediation
View remediation

T02 · Agent Memory Poisoning

Error
Location
scripts/auto_ingest.py:99
Finding

Untrusted Markdown Can Poison Persistent Agent Memory

Content
View full analysis
4000: text = text[:4000] + "\n\n[... truncated ...]" context = f"[Source: {filepath}]\n\n{text}" if debug: print(f" 📄 Extracting from {filepath} ({len(text)} chars)...", file=sys.stderr) facts = extract_facts(context, cfg, debug) ``` The extraction function interpolates that untrusted content into the instruction text: ```python EXTRACTION_PROMPT = """You are a fact extractor. You receive text from conversations or documents. RULES: - Extract ONLY durable facts (true tomorrow, not just today) - Ignore one-time actions ("I ran the build", "I sent the message") - Ignore conversation filler (greetings, confirmations) - Each fact must be self-contained (understandable without context) - Confidence: 0.0 to 1.0 (only return >= 0.5) - Categories: savoir, erreur, chronologie, preference, outil, client, rh TEXT: {text} Return JSON: {{"facts": [ {{"fact": "concise fact statement", "category": "category", "confidence": 0.8}}, ... ]}} Return empty facts array if nothing durable found: {{"facts": []}}""" ``` ```python # Truncate to avoid overwhelming the LLM text = text[:4000] prompt = EXTRACTION_PROMPT.format(text=text) result = call_llm_json(prompt, cfg, debug) if result and "facts" in result: # Filter by confidence return [f for f in result["facts"] if f.get("confidence", 0) >= 0.5] ``` Model-generated facts are then persisted: ```python result = store.store( fact=f["fact"], category=f.get("category", "kno ...[truncated 2366 chars]
Remediation
View remediation

T06 · System Persistence

Warning
Location
references/configuration.md:55
Finding

Persistent Scheduled Ingestion Uses Ambiguous Relative Execution Paths

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:34
Finding

Optional QMD Dependency Is Installed Globally Without Version or Integrity Pinning

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/auto_ingest.py:181
Finding

Sensitive Workspace Content and Recall Queries Are Retained in Plaintext Cache Files

Content
View full analysis
20: new_chunks.append({ "filepath": os.path.abspath(fp), "text": chunk_text, "chunk_index": chunk_idx, }) pos = end - overlap_chars if end < len(text) else end chunk_idx += 1 if not new_chunks: return # Embed new chunks texts = [c["text"] for c in new_chunks] vectors = embed(texts, cfg, debug) if vectors and len(vectors) == len(new_chunks): for c, v in zip(new_chunks, vectors): c["embedding"] = v chunks.extend(new_chunks) cache["chunks"] = chunks cache["updated_at"] = datetime.now().isoformat() with open(cache_path, "w") as f: json.dump(cache, f) ``` Extracted facts are also written as plaintext JSON: ```python def _save_local(path: Path, facts: list): path.write_text(json.dumps(facts, ensure_ascii=False, indent=2)) ``` Recall questions and result metadata are appended to a persistent log: ```python entry = { "timestamp": datetime.now().isoformat(), "question": question, "confidence": result.get("confidence", 0), "total_results": result.get("stats", {}).get("total_results", 0), "per_source": result.get("stats", {}).get("per_source", {}), "total_time": result.get("stats", {}).get("total_time", 0), "top_results": [ { ...[truncated 2043 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (65)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The documented setup pattern includes installing software via remote shell script and pulling models, while the skill is presented mainly as a local memory toolkit. In practice, encouraging operators to run bootstrap commands with shell/network side effects can introduce supply-chain risk and unexpected system modification, especially when framed as routine setup for a memory tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The documented setup pattern includes installing software via remote shell script and pulling models, while the skill is presented mainly as a local memory toolkit. In practice, encouraging operators to run bootstrap commands with shell/network side effects can introduce supply-chain risk and unexpected system modification, especially when framed as routine setup for a memory tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The documented setup pattern includes installing software via remote shell script and pulling models, while the skill is presented mainly as a local memory toolkit. In practice, encouraging operators to run bootstrap commands with shell/network side effects can introduce supply-chain risk and unexpected system modification, especially when framed as routine setup for a memory tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The documented setup pattern includes installing software via remote shell script and pulling models, while the skill is presented mainly as a local memory toolkit. In practice, encouraging operators to run bootstrap commands with shell/network side effects can introduce supply-chain risk and unexpected system modification, especially when framed as routine setup for a memory tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The documented setup pattern includes installing software via remote shell script and pulling models, while the skill is presented mainly as a local memory toolkit. In practice, encouraging operators to run bootstrap commands with shell/network side effects can introduce supply-chain risk and unexpected system modification, especially when framed as routine setup for a memory tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The documented setup pattern includes installing software via remote shell script and pulling models, while the skill is presented mainly as a local memory toolkit. In practice, encouraging operators to run bootstrap commands with shell/network side effects can introduce supply-chain risk and unexpected system modification, especially when framed as routine setup for a memory tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The documented setup pattern includes installing software via remote shell script and pulling models, while the skill is presented mainly as a local memory toolkit. In practice, encouraging operators to run bootstrap commands with shell/network side effects can introduce supply-chain risk and unexpected system modification, especially when framed as routine setup for a memory tool.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The documented setup pattern includes installing software via remote shell script and pulling models, while the skill is presented mainly as a local memory toolkit. In practice, encouraging operators to run bootstrap commands with shell/network side effects can introduce supply-chain risk and unexpected system modification, especially when framed as routine setup for a memory tool.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill metadata claims it runs 100% locally with no cloud dependency, but this module will send stored facts and queries to a remote Convex service whenever convexUrl is configured. That mismatch can mislead users into exposing sensitive workspace memory or extracted facts to an external service under the assumption that all processing is local.

Content

No source excerpt is available for this finding.

External Script Fetching

High
Category
Supply Chain
Confidence
97% confidence
Finding

This line retrieves executable content from an external URL and passes it straight to the shell, creating an external script fetching vulnerability. The danger is amplified in a setup script because users expect it to prepare their environment and may run it without scrutiny, granting remote content direct execution on their machine.

Content

Scanner excerpt · setup.sh (reported line 39)May include surrounding context.

sh
echo "  → Download from https://ollama.com/download/mac"
    echo "  → Or: brew install ollama"
  elif [[ "$OSTYPE" == "linux"* ]]; then
    echo "  → Running: curl -fsSL https://ollama.com/install.sh | sh"
    curl -fsSL https://ollama.com/install.sh | sh
  else
    echo "  → Download from https://ollama.com/download"

External Script Fetching

High
Category
Supply Chain
Confidence
97% confidence
Finding

The actual execution of the fetched installer occurs here, so compromise of the remote source or delivery path would result in arbitrary shell command execution. Because this is in an installation path, successful exploitation could persist software, modify shell profiles, or alter system state broadly.

Content

Scanner excerpt · setup.sh (reported line 40)May include surrounding context.

sh
echo "  → Or: brew install ollama"
  elif [[ "$OSTYPE" == "linux"* ]]; then
    echo "  → Running: curl -fsSL https://ollama.com/install.sh | sh"
    curl -fsSL https://ollama.com/install.sh | sh
  else
    echo "  → Download from https://ollama.com/download"
  fi

Chaining Abuse

High
Category
Tool Misuse
Confidence
96% confidence
Finding

The pipe into sh is the hazardous chaining primitive that converts downloaded text into immediate command execution. In a shell setup script this meaningfully increases exploitability because there is no inspection boundary between receipt of remote data and execution.

Content

Scanner excerpt · setup.sh (reported line 40)May include surrounding context.

sh
echo "  → Or: brew install ollama"
  elif [[ "$OSTYPE" == "linux"* ]]; then
    echo "  → Running: curl -fsSL https://ollama.com/install.sh | sh"
    curl -fsSL https://ollama.com/install.sh | sh
  else
    echo "  → Download from https://ollama.com/download"
  fi

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README makes a strong trust claim that the skill runs '100% local' with 'no cloud dependency,' but elsewhere advertises optional Convex cloud storage and OpenAI/OpenRouter presets. This mismatch can mislead users into installing or enabling the skill under an incorrect privacy and data-flow assumption, increasing the risk of unintended transmission of workspace-derived data to remote services.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README promotes auto-ingestion and workspace watching without a prominent warning that files may be continuously monitored, parsed, and stored as extracted facts or graph data. In a memory/indexing skill, this is security-relevant because users may accidentally ingest sensitive local content, credentials, personal data, or proprietary information without understanding the persistence scope.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill advertises capabilities that inherently involve shell execution, file reads/writes, and environment access, but the manifest does not declare any explicit tool scope or permission boundaries. In an agent setting, this increases the chance of over-privileged or unintended execution because callers cannot easily constrain what the skill is allowed to touch.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest asserts '100% local' and 'no cloud dependency' while the same document describes optional remote/OpenAI and Convex-backed operation. This is security-relevant because users may make trust decisions about sensitive memory data based on those privacy claims and unknowingly enable remote processing or storage.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger description is broad enough to match common agent activities such as memory recall, knowledge search, indexing, and fact extraction, which can cause the skill to be invoked more often than intended. Because the skill can read/write files and run shell-based workflows, accidental invocation raises the risk of unnecessary data access, ingestion of sensitive workspace content, or side effects from indexing/watch operations.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Saying the skill runs locally via Ollama while also documenting OpenAI and Convex options creates materially misleading expectations about data residency. In the context of agent memory, that can result in accidental disclosure of indexed files, extracted facts, or recall queries to remote services.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · references/configuration.md (reported line 25)May include surrounding context.

macOS (LaunchAgent)

xml
<!-- ~/Library/LaunchAgents/com.memory-auto-ingest.plist -->
<plist version="1.0">
<dict>
    <key>Label</key><string>com.memory-auto-ingest</string>

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · references/configuration.md (reported line 26)May include surrounding context.

macOS (LaunchAgent)

xml
<!-- ~/Library/LaunchAgents/com.memory-auto-ingest.plist -->
<plist version="1.0">
<dict>
    <key>Label</key><string>com.memory-auto-ingest</string>

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · references/configuration.md (reported line 40)May include surrounding context.

macOS (LaunchAgent)

xml
<!-- ~/Library/LaunchAgents/com.memory-auto-ingest.plist -->
<plist version="1.0">
<dict>
    <key>Label</key><string>com.memory-auto-ingest</string>

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The script automatically reads markdown files from the workspace and forwards their contents to fact extraction without any normal-operation disclosure or consent gate. Even though the skill metadata says processing is local via Ollama, this still creates a meaningful privacy/security risk because potentially sensitive workspace data is automatically ingested and propagated into other storage systems.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

Changed file contents are re-chunked and sent to the embedding pipeline automatically, again without a clear disclosure at the point of use. In this skill context, embeddings are described as local, which reduces remote exfiltration risk, but sensitive document text is still copied into caches and transformed into derived data that may outlive the source files.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/auto_ingest.py (reported line 292)May include surrounding context.

python
use_fswatch = False
    if sys.platform == "darwin":
        try:
            subprocess.run(["which", "fswatch"], capture_output=True, check=True)
            use_fswatch = True
        except (subprocess.CalledProcessError, FileNotFoundError):
            pass

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/auto_ingest.py (reported line 309)May include surrounding context.

python
"-e", r"\.cache", "-e", r"__pycache__", "-e", r"\.git",
           "-i", r"\.md$"] + watch_paths
    
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, text=True)
    pending = {}
    
    while True: