Back to skill

Security audit

MindClaw

Security checks for vulnerabilities and agentic risk

Overview

MindClaw is a coherent persistent-memory skill, but it gives agents broad long-term storage, import/export, prompt-context, and mutation powers with under-scoped safeguards for sensitive data and per-agent isolation.

Review before installing. Use a dedicated database and agent namespace, avoid storing secrets or regulated data, keep Ollama/local services trusted, back up memory files before sync/import, and do not let agents call setup, import, capture, sync, or hard-delete tools without explicit user approval.

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 (4)

T02 · Agent Memory Poisoning

Error
Location
src/mindclaw/store.py:748
Finding

Persistent Prompt Injection Through Unsanitized Memory Content

Content
View full analysis
int: # ... for line in text.splitlines(): stripped = line.strip() # Category headings if stripped.startswith("#"): heading = stripped.lstrip("#").strip().lower() current_category = next( (cat for key, cat in cat_map.items() if key in heading), "note", ) continue # Bullet points → memories if stripped.startswith(("- ", "* ", "+ ")): content = stripped[2:].strip() if len(content) < 5: continue tags = _re.findall(r"`([^`]+)`", content) content_clean = _re.sub(r"\s*`[^`]+`", "", content).strip(" 📌").strip() if not content_clean or content_clean.lower() in seen: continue m = Memory( content=content_clean, category=current_category, tags=tags, source=source or str(target), agent_id=agent_id, created_at=file_date or time.time(), ) self.add(m) ``` The imported content is later rendered directly into an LLM context block: ```python HEADER = "## Relevant memories\n" FOOTER = "\n## End of memories\n" MEMORY_TEMPLATE = ( "[{id}] ({category}, importance={importance:.2f}{pinned_marker}) {content}" ) # ... line = self.MEMORY_TEMPLATE.format( id=mem.id, category=mem.category, importance=mem.importance, pinned_marker=pinned_marker + conf_marker, content=mem.content, ) # ... def build_system_prom ...[truncated 2472 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/mindclaw/mcp_server.py:293
Finding

Cross-Namespace Memory Modification Through ID-Only Authorization

Content
View full analysis
dict: store = _get_store() mem = store.confirm(memory_id) if mem is None: return {"confirmed": False, "error": f"Memory {memory_id} not found"} return { "confirmed": True, "id": mem.id, "new_importance": mem.importance, "confirmed_count": mem.confirmed_count, } @mcp.tool() def forget(memory_id: str, hard: bool = False) -> dict: store = _get_store() if hard: ok = store.delete(memory_id) action = "deleted" else: ok = store.archive(memory_id) action = "archived" return {"success": ok, "action": action, "id": memory_id} @mcp.tool() def pin_memory(memory_id: str) -> dict: store = _get_store() ok = store.pin(memory_id) return {"pinned": ok, "id": memory_id} @mcp.tool() def unpin_memory(memory_id: str) -> dict: store = _get_store() ok = store.unpin(memory_id) return {"unpinned": ok, "id": memory_id} ``` The corresponding storage operations authorize only by memory ID: ```python def delete(self, memory_id: str) -> bool: with self._conn() as conn: cur = conn.execute("DELETE FROM memories WHERE id = ?", (memory_id,)) return cur.rowcount > 0 def archive(self, memory_id: str) -> bool: with self._conn() as conn: row = conn.execute( "SELECT pinned FROM memories WHERE id = ?", (memory_id,) ).fetchone() if row and row["pinned"]: return False cur = conn.execute( "UPDATE memories SET archived = 1, updated_at = ? WHERE id = ?", (time.time(), memory_id), ) retur ...[truncated 2279 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/mindclaw/capture.py:77
Finding

Incomplete Credential Redaction Persists Plaintext Secrets

Content
View full analysis
str: """Replace potential secrets with [REDACTED].""" redacted = re.sub( r'((?:key|token|password|secret|credential)\s*[:=]\s*)(\S+)', r'\1[REDACTED]', text, flags=re.IGNORECASE, ) return redacted ``` ### Technical Analysis Credential detection and credential redaction use different grammars. The detector accepts phrases such as `API key is SECRET_VALUE`, while the redactor requires the credential keyword to be followed directly by `:` or `=`. Consequently, a line can be classified as a credential and assigned high importance while the actual secret remains unchanged. Both `content` and the generated `summary` then contain the plaintext li ...[truncated 1286 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/mindclaw/store.py:124
Finding

Sensitive Memory and Configuration Files Lack Explicit Owner-Only Permissions

Content
View full analysis
str: """Write config to ~/.mindclaw/config.json. Returns the path written.""" _CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True) _CONFIG_PATH.write_text( json.dumps(asdict(cfg), indent=2, default=str), encoding="utf-8", ) return str(_CONFIG_PATH) ``` ### Technical Analysis Neither path explicitly enforces owner-only permissions. The resulting mode is determined by the process umask and existing parent-directory permissions. On a system with a permissive umask or pre-existing permissive directory, the database or configuration can become readable or writable by other local users. The database is security-sensitive because it stores long-term conversation-derived memory and metadata in plaintext. The credential-redaction weakness documented separately further increases the sensitivity of the stored data. The configuration also controls database, workspace, and namespace paths, so unauthorized modification could redirect storage or synchronization. ### Attack Path 1. MindClaw runs under a permissive umask or uses an existing `.mindclaw` directory with permissive permissions. 2. The database or configuration file is created without an explicit restrictive mode. 3. Another local account reads `memory.db` or `config.json`, or modifies the configuration if write permiss ...[truncated 622 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (29)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
93% confidence
Finding

The credential rule intentionally detects secret-bearing lines and stores the redacted full line as a memory, which still persists sensitive security context and may fail to fully remove secrets if formatting differs from the redaction regex. Because capture happens automatically, users may unknowingly cause API keys, passwords, or adjacent confidential metadata to be written to storage, increasing exposure through logs, search, backups, or later retrieval.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
78% confidence
Finding

The README strongly encourages persistent retention of agent/user information ('Remember everything, forget nothing') and synchronization into searchable memory stores. In an agent context, this can normalize storing sensitive conversations, credentials, or personal data without sufficient minimization, consent, or retention boundaries, increasing the chance of later disclosure through search, sync, or prompt-context injection.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

This markdown file instructs users to run installation and setup commands that automatically register with Claude Desktop/OpenClaw and later describes sync/import features that update ~/.mindclaw/config.json, tool registries, and MEMORY.md. Although the behavior is described, there is no explicit user-facing warning section calling out that these commands will write to config files and modify existing memory documents, which is relevant to user data and system integrity.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The markdown advertises forget <id> --hard and later states the MCP tool can 'Archive or delete a memory', but it does not provide a clear warning that hard delete is destructive and may be irreversible. For markdown files, omission of warnings around destructive behavior affecting user data should be flagged.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The recommended agent loop explicitly instructs agents to capture conversations, persist memories, and inject retrieved context into future prompts. In practice, this creates a clear data leakage path where confidential user inputs may be extracted, stored long-term, surfaced to other tasks, or reintroduced into model prompts beyond the original purpose.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% 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 · README.md (reported line 340)May include surrounding context.

md
| `context.py` | Token-aware context block builder, conflict detection, cluster summarization |
| `graph.py` | Knowledge graph — edge CRUD, shortest-path, subgraph traversal |
| `capture.py` | Rule-based extraction of facts, decisions, errors, prefs from free text |
| `config.py` | Persistent config file — read/write `~/.mindclaw/config.json` |
| `cli.py` | Argument parser and all command handlers |
| `mcp_server.py` | FastMCP server factory, **15 MCP tools**, Claude Desktop + OpenClaw install helpers |

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% 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 · README.md (reported line 368)May include surrounding context.

md
| `context.py` | Token-aware context block builder, conflict detection, cluster summarization |
| `graph.py` | Knowledge graph — edge CRUD, shortest-path, subgraph traversal |
| `capture.py` | Rule-based extraction of facts, decisions, errors, prefs from free text |
| `config.py` | Persistent config file — read/write `~/.mindclaw/config.json` |
| `cli.py` | Argument parser and all command handlers |
| `mcp_server.py` | FastMCP server factory, **15 MCP tools**, Claude Desktop + OpenClaw install helpers |

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This skill explicitly provides tools to store, sync, archive, and hard-delete persistent memory, including exporting data into OpenClaw's MEMORY.md, but it does not warn users that invoking these tools can modify or permanently remove stored data. That omission can lead users or agents to perform destructive or privacy-impacting actions without informed consent, especially because the skill is framed as a seamless memory layer integrated into agent workflows.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The description 'Remember everything, forget nothing' communicates unbounded retention and collection scope without clear minimization limits. In a memory tool used by agents, this can encourage storage of sensitive prompts, credentials, personal data, or proprietary context beyond user expectations, increasing privacy and data-exposure risk.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The combined messaging promotes indiscriminate, persistent retention of agent/user information and synchronization into external memory files. In the context of an agent memory skill, this makes accidental long-term storage of sensitive conversation data more likely and expands the blast radius if the memory store or synced files are later accessed by other tools or users.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest advertises syncing to MEMORY.md and importing logs, which implies modifying and ingesting local data, but it provides no warning, confirmation model, or safety caveat. In agent environments, silent file writes/imports can overwrite user-managed memory files, ingest sensitive local content, or persist unintended information without informed consent.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The auto-capture and markdown import features semantically encourage broad harvesting of text, decisions, errors, preferences, TODOs, and daily logs into persistent memory. Because this is a memory/knowledge-graph skill, that behavior is especially risky: it can sweep in credentials, personal data, confidential project notes, or prompt content at scale, then make them searchable and durable.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest documents setup and setup_mindclaw as commands that save configuration and perform onboarding, and the config comments describe a persistent config file written by mindclaw setup. However, lines L154-L158 show a malformed YAML structure (config: config_file: and merged fields) that does not actually define the documented configuration keys as described. This is an intent/documentation contradiction within the file itself, not merely missing detail.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The auto-capture engine persists extracted conversation content to the memory store by default, including when processing full conversations, without any consent, notice, or approval gate in this code path. In systems handling chats, logs, or mixed-sensitivity user input, this creates a privacy and data-retention risk because users may disclose personal, confidential, or regulated information that is silently stored and later retrievable.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The capture command accepts free text, stdin, or a file and passes that content into AutoCapture for storage, but there is no disclosure that personal, confidential, or system-sensitive text may be extracted and saved. Although dry-run mode exists, normal operation persists derived memories and the help strings do not warn about that behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The md-import command imports memories from an arbitrary Markdown file path and persists extracted content, but the command's help text and function messaging do not warn that local notes or logs may contain sensitive information that will be stored. For this rule, reading user files and persisting their contents is a safety-relevant data operation that should include some disclosure when not already clearly warned elsewhere in this file.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% 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 · src/mindclaw/config.py (reported line 94)May include surrounding context.

python
def save_config(cfg: MindClawConfig) -> str:
    """Write config to ~/.mindclaw/config.json.  Returns the path written."""
    _CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
    _CONFIG_PATH.write_text(
        json.dumps(asdict(cfg), indent=2, default=str),

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% 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 · src/mindclaw/mcp_server.py (reported line 55)May include surrounding context.

python
# ---------------------------------------------------------------------------

def _get_store() -> MemoryStore:
    """Create a store using env var > config file > built-in default."""
    from .config import load_config
    cfg = load_config()
    db_path = cfg.effective_db()

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The capture tool is explicitly designed to extract and store information from arbitrary text, including credentials, and it persists results by default unless dry_run is set. In a conversational agent setting, this can lead to unintentional retention of secrets or sensitive personal data from prompts, logs, or transcripts without a user-facing confirmation step or redaction control.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The setup_mindclaw tool performs persistent side effects even when key parameters are omitted: it writes configuration, may register the MCP server with OpenClaw, and may sync data using default paths. In an agent-tooling context, that is risky because an LLM or workflow could invoke it without explicit user approval, causing unintended local configuration changes and data export to another workspace.

Content

No source excerpt is available for this finding.

Tainted flow: 'req' from urllib.request.urlopen (line 178, network input) → urllib.request.urlopen (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · src/mindclaw/search.py (reported line 199)May include surrounding context.

python
data=data,
                headers={"Content-Type": "application/json"},
            )
            with urllib.request.urlopen(req, timeout=10) as resp:
                result = json.loads(resp.read())
                return result.get("embedding")
        except Exception:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The search engine transmits user queries and stored memory content to a local Ollama HTTP service for embeddings without any consent, warning, or policy gate in this file. Even though the default target is localhost, this still expands the trust boundary and can expose sensitive memory content to another process, and base_url is configurable so deployment mistakes could send data to a remote host.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The top-level documentation describes this module as a 'SQLite-backed persistent memory store' focused on storing memories in structured records. Later code adds import/export and synchronization behavior that reads and writes arbitrary Markdown files and auto-targets an OpenClaw workspace, which is a materially broader behavior than the module description suggests.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This file exports stored memories into Markdown files and later syncs them into an OpenClaw workspace, which can persist potentially sensitive user data outside the database. Although the functions have docstrings, there is no confirmation prompt, logging, or explicit warning that memory contents will be written to files in another workspace location.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The import_from_markdown path reads a Markdown file and converts bullet content into persistent memories, which can capture and retain potentially sensitive information from user files. The code includes internal docstrings, but no visible confirmation, logging, or warning to the user that file contents will be ingested into the persistent store.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.