Back to skill

Security audit

Mind-Wander

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent background-research purpose, but it installs recurring autonomous execution with broad local/network access and an unsafe code runner without enough user control.

Install only if you intentionally want a recurring background agent with access to your OpenClaw workspace, graph memory, local model endpoint, Perplexity API, and host-level Python execution. Review or remove the cron registration, disable or replace sandbox_run, pin dependencies/model artifacts, and avoid using this in workspaces containing secrets or sensitive notes until those controls are improved.

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

T06 · System Persistence

Error
Location
scripts/install.sh:168
Finding

Installer Creates a Persistent Autonomous Scheduled Task Without Explicit Opt-In

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/tools.py:220
Finding

Model-Generated Python Runs Without an Effective Security Sandbox

Content
View full analysis
dict: """ Run a short Python snippet in isolation. Max 50 lines, 30s timeout, no network, restricted imports. No file writes. Use for quick hypothesis testing only. """ lines = code.strip().split("\n") if len(lines) > SANDBOX_MAX_LINES: return {"ok": False, "result": "", "error": f"Code too long ({len(lines)} lines, max {SANDBOX_MAX_LINES})"} # Block dangerous imports/operations BLOCKED = ["subprocess", "socket", "urllib", "requests", "httpx", "open(", "os.system", "os.popen", "eval(", "exec(", "__import__", "importlib", "ctypes", "shutil", "glob"] for blocked in BLOCKED: if blocked in code: return {"ok": False, "result": "", "error": f"Blocked operation: '{blocked}'"} # Wrap in a safe exec with limited builtins safe_code = textwrap.dedent(f""" import sys, math, statistics, itertools, functools, collections, re, json, datetime try: import numpy as np except ImportError: pass try: import scipy except ImportError: pass {code} """) try: # Run in subprocess with timeout and no network result = subprocess.run( ["python3", "-c", safe_code], capture_output=True, text=True, timeout=SANDBOX_TIMEOUT, ) output = result.stdout + result.stderr if len(output) > 500: output = output[:500] + "\n[...truncated]" return { "ok": result.returncode == 0, "result": output or "(no output)", "error": None if result.returncode == 0 else f"Exit code {result.returncode}", } except subprocess.TimeoutExpired: return {"ok": False, "result": " ...[truncated 2035 chars]
Remediation
View remediation

T02 · Agent Memory Poisoning

Error
Location
scripts/tools.py:319
Finding

Untrusted Retrieved Content Can Be Written Into Persistent Agent Memory

Content
View full analysis
tuple[str, str]: from mind_wander_config import MAX_TOOL_CALLS system = SYSTEM_PROMPT.format(max_tools=MAX_TOOL_CALLS) # Read ON_YOUR_MIND.md if ON_YOUR_MIND_FILE.exists(): on_your_mind = ON_YOUR_MIND_FILE.read_text(errors="replace") else: on_your_mind = "(ON_YOUR_MIND.md not found — nothing to explore)" # Read recent state to avoid re-running same items state = _load_state() runs = state.get("runs", {}) now = time.time() cooldown_secs = COOLDOWN_HOURS * 3600 recently_run = [item for item, ts in runs.items() if now - ts < cooldown_secs] # Pull graph context for the anchor item graph_context = "" if anchor_item: result = query_graph(anchor_item, limit=GRAPH_LIMIT) if result["ok"] and result["result"]: graph_context = f"\n\nGraph context for '{anchor_item}':\n{result['result']}" else: result = query_graph("active projects recent decisions open questions", limit=5) if result["ok"]: graph_context = f"\n\nGraph orientation:\n{result['result']}" user_message = f"""ON_YOUR_MIND.md contents: --- {on_your_mind} --- {graph_context} {dead_end_context} {"Recently explored (avoid re-exploring within " + str(COOLDOWN_HOURS) + "h): " + ", ".join(recently_run) if recently_run else ""} {"Focus on this specific item: " + anchor_item if anchor_item else "Pick the most interesting unresolved item to explore."} Begin. Remember: explore ONE thread. Use tools. Elevate only if genuinely novel. \ If nothing novel surfaces after a few tool calls, say so briefly and stop.""" ``` ```python # scripts/tools.py d ...[truncated 3087 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/tools.py:103
Finding

Workspace Content Can Be Forwarded to an External Search Provider

Content
View full analysis
dict: """ Search Perplexity AI for current external information. Requires PERPLEXITY_API_KEY. """ api_key = PERPLEXITY_KEY # Try to read from openclaw.json if not set if not api_key: try: config_path = Path.home() / ".openclaw" / "openclaw.json" with open(config_path) as f: cfg = json.load(f) api_key = (cfg.get("plugins", {}) .get("entries", {}) .get("perplexity", {}) .get("config", {}) .get("webSearch", {}) .get("apiKey", "")) except Exception: pass if not api_key: return {"ok": False, "result": "", "error": "No Perplexity API key configured"} try: import httpx resp = httpx.post( "https://api.perplexity.ai/chat/completions", headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}, json={ "model": "sonar", "messages": [{"role": "user", "content": query}], "max_tokens": 800, }, timeout=30, ) resp.raise_for_status() d = resp.json() text = d["choices"][0]["message"]["content"] citations = d.get("citations", []) result = text if citations: result += "\n\nSources:\n" + "\n".join(f"- {c}" for c in citations[:5]) return {"ok": True, "result": result, "error": None} except Exception as e: return {"ok": False, "result": "", "error": f"Web search failed: {e}"} ``` ```python def read_file(path: str) -> dict: """ Read a works ...[truncated 2625 chars]
Remediation
View remediation

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/install.sh:72
Finding

Installer Downloads and Executes an Unverified Remote Python Bootstrap Script

Content
View full analysis
/dev/null; then if ! command -v pip3 &>/dev/null; then run curl -sS https://bootstrap.pypa.io/get-pip.py -o /tmp/get-pip.py run python3 /tmp/get-pip.py --user --break-system-packages --quiet fi run pip3 install --user --break-system-packages --quiet huggingface_hub httpx falkordb numpy log " ✅ Packages installed" else log " ✅ Already present" fi ``` ### Technical Analysis When `pip3` is unavailable, the installer downloads `get-pip.py` from a remote URL and immediately executes it. It does not pin a specific immutable revision, verify a cryptographic hash or signature, or inspect the downloaded file. The effective code executed during installation can therefore change after this Skill package has been audited. HTTPS protects the transport connection but does not establish that a particular reviewed payload was received. The use of the predictable shared path `/tmp/get-pip.py` also creates unsafe temporary-file behavior on multi-user systems because the installer does not create the file atomically in a private directory. ### Attack Path 1. A user runs the installer on a system without `pip3`. 2. The installer downloads the current contents of `get-pip.py`. 3. No expected digest or signature is checked. 4. The installer executes the downloaded Python under the user's account. 5. If the upstream content, delivery path, or temporary file is compromised, arbitrary Python runs with the installer's privileges. ### Impact Assessment A compromised payload receives arbitrary Python execution as the user running installation. It can access that user's files, workspace, environment, credentials, network re ...[truncated 230 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
scripts/install.sh:78
Finding

Python Dependencies and the Tool-Controlling LLM Artifact Are Not Cryptographically Pinned

Content
View full analysis
&1 || log " ⚠️ Register failed — see references/setup.md for manual steps" ``` ### Technical Analysis The installer requests the latest available versions of `huggingface_hub`, `httpx`, `falkordb`, and `numpy` without version constraints or package hashes. A future install may therefore receive code that differs from the versions reviewed with this project. The GGUF model is downloaded from a third-party Hugging Face repository by repository and filename only. No immutable repository revision, commit identifier, expected digest, or signature is provided. The model is security-sens ...[truncated 1324 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (30)

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

A description-behavior mismatch around graph isolation is security-relevant because the skill claims exploration will stay in a separate 'wander' graph, but the detected behavior indicates it may use the primary 'workspace' graph instead. That can contaminate the main memory/context with exploratory or dead-end material, undermine trust boundaries, and cause unintended persistence of low-confidence or sensitive research artifacts.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The collector is explicitly designed to store full conversation transcripts, system prompts, tool outputs, ON_YOUR_MIND snapshots, and graph context to disk as training records. In this skill's context, that is especially dangerous because background reasoning may ingest sensitive internal context, secrets, proprietary research notes, or system instructions, creating a durable local trove of high-value data that could later be exposed, reused unsafely for training, or accessed by other components/users.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The installer registers a recurring 30-minute cron job that triggers future agent executions, but does not obtain explicit informed consent at the time it does so. This creates durable autonomous behavior after install, increasing the risk of unexpected resource use, data access, and follow-on actions in the workspace.

Content

No source excerpt is available for this finding.

Ssd 4

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The scheduled payload instructs the agent to write a helper script to /tmp and then execute it, framing this as routine background work. This is a classic indirect execution chain: instead of performing a bounded action directly, it prompts an agent to generate code and run it, which expands the attack surface and weakens auditability.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The documented sandbox guarantees are materially false: the implementation launches arbitrary Python in a normal interpreter process and only blocks a small set of string literals. In an autonomous research agent that can generate its own code, this greatly increases the chance of sandbox escape, workspace tampering, secret access, or local system abuse.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill advertises broad capabilities including file read/write, network access, shell execution, and environment access, but does not declare any explicit tool scope or permission boundaries. For an autonomous scheduled agent, this is dangerous because it can perform persistent writes, external data exfiltration, or arbitrary local actions without a clear least-privilege contract or user-facing restriction.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The description emphasizes autonomous research benefits but does not prominently warn that the skill performs scheduled web searches and writes persistent files that may later enter the main memory pipeline. Missing disclosure reduces informed consent and increases the risk of users unintentionally enabling continuous external access and durable state changes.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The trigger list contains broad phrases like 'background reasoning', 'dead ends', and 'explore while I sleep' that could match normal conversation and activate an autonomous agent unexpectedly. In this context, accidental activation is more dangerous because the skill can schedule research, run tools, perform web searches, and write persistent outputs without an explicit per-run confirmation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This markdown file states that the installer initializes a database graph, creates a 30-minute cron job, and creates a local file, all of which modify the user's system or data. The section does not include a warning or caution about these side effects, so users may not realize installation changes system scheduling and filesystem state.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manual cron registration example performs an authenticated API call that schedules recurring execution of agent-supplied code, including writing and running a Python script from a message payload. In the context of an autonomous research skill, this materially increases danger because it establishes persistence and indirect code execution through the gateway without strong warnings, scope restrictions, or guidance on least-privilege credentials.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The llm_call function sends the system prompt and message history to WANDER_OLLAMA over HTTP, which can include user or system-derived context. Although the module docstring mentions driving the model, there is no explicit user-facing warning, confirmation, or privacy notice in this file about transmitting that data to an external or configured endpoint.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code logs session metadata at startup and later saves the full system prompt, user message context, assistant messages, and tool outputs via save_session, but the file provides no user-facing warning, confirmation, or inline disclosure that conversation content will be recorded. Because this is a code file performing persistent writes of potentially sensitive model and tool data, it meets the missing-warning criteria.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The agent persistently stores full system prompts, user context snapshots, model outputs, and raw tool results, which may include secrets, sensitive local data, or results from sandbox/web-search tools. In a background autonomous research skill, this is more dangerous because it runs unattended and accumulates long-lived transcripts, increasing the blast radius of any later file, log, or database compromise.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code persists system_prompt, full messages, and additional context snapshots to a JSON file, which can include sensitive user or system data. Although the module docstring describes the output format, there is no user-facing disclosure, confirmation, or visible warning in the code around this capture-and-write behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The installer copies scripts into the workspace without a clear up-front warning or confirmation. While file installation is common, silently writing executable content into a user workspace can create trust and provenance issues, especially in an agent ecosystem where newly placed scripts may later be invoked automatically.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
71% confidence
Finding

Creating ON_YOUR_MIND.md establishes persistent state in the workspace that will be consumed by later autonomous runs. Persistent state is not inherently malicious, but in this skill it directly feeds future background reasoning sessions, so unannounced creation increases the chance of unexpected long-lived behavior.

Content

Scanner excerpt · scripts/install.sh (reported line 139)May include surrounding context.

sh
log "  ✅ Wander graph initialised"
fi

# Step 5: Create ON_YOUR_MIND.md template
ON_YOUR_MIND="$WORKSPACE/ON_YOUR_MIND.md"
if [[ ! -f "$ON_YOUR_MIND" ]]; then
  log "Creating ON_YOUR_MIND.md template..."

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The installer reads a local gateway auth token from the user's OpenClaw config and uses it to create a recurring cron job that later drives agent execution. This is dangerous because it silently converts a one-time install into ongoing privileged automation, using local credentials to schedule future behavior the user may not understand or expect.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The scheduled prompt tells the agent to print captured stdout and stderr back in its reply. That can expose workspace paths, runtime details, model output, or other sensitive execution context in natural-language responses, which may be logged, surfaced to users, or stored in system history.

Content

No source excerpt is available for this finding.

Internal Network Request

Medium
Category
Server-Side Request Forgery
Confidence
70% confidence
Finding

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

Scanner excerpt · scripts/install.sh (reported line 193)May include surrounding context.

sh
"delivery": {"mode": "none"},
            "sessionTarget": "isolated"
        }
        resp = httpx.post(f"http://localhost:{port}/api/cron/jobs",
            headers={"Authorization": f"Bearer {token}"}, json=job)
        if resp.status_code in (200, 201):
            print(f"  ✅ Cron registered (id: {resp.json().get('id','')})")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The tool silently retrieves a local API key from ~/.openclaw/openclaw.json and transmits user/model-supplied queries to a third-party service. In an autonomous agent, this creates privacy and data-governance risk because workspace-derived or sensitive prompts may be exfiltrated without explicit runtime consent or visibility.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

This code sends query content to api.perplexity.ai, creating an external data transmission path. In the context of a background reasoning skill that may process local notes and unresolved questions, this can leak sensitive workspace information or personal data to a third party.

Content

Scanner excerpt · scripts/tools.py (reported line 129)May include surrounding context.

python
try:
        import httpx
        resp = httpx.post(
            "https://api.perplexity.ai/chat/completions",
            headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
            json={

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The hardcoded external endpoint confirms third-party transmission of prompt content outside the local environment. This is particularly sensitive for an autonomous skill because users may not realize that internal research topics and notes are being sent off-device.

Content

Scanner excerpt · scripts/tools.py (reported line 130)May include surrounding context.

python
try:
        import httpx
        resp = httpx.post(
            "https://api.perplexity.ai/chat/completions",
            headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
            json={
                "model": "sonar",

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

read_file claims to read only workspace Markdown files, but it actually reads any file under the workspace path. In a background agent, this broadens access to secrets, config files, SSH material, datasets, or other sensitive local artifacts that the model was not intended to inspect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The tool executes arbitrary Python generated by the agent without clear user-facing disclosure at the moment of execution. Because this is an autonomous background-reasoning skill, hidden code execution materially raises the risk of local compromise, destructive actions, and unexpected system interaction.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
98% confidence
Finding

The tool executes model-supplied Python via subprocess.run(["python3", "-c", safe_code]) while relying only on naive substring blocking for safety. This is not a real sandbox: an attacker can likely bypass the denylist, access files, consume resources, or invoke dangerous functionality despite documentation claiming isolation and no file writes.

Content

Scanner excerpt · scripts/tools.py (reported line 257)May include surrounding context.

python
try:
        # Run in subprocess with timeout and no network
        result = subprocess.run(
            ["python3", "-c", safe_code],
            capture_output=True, text=True,
            timeout=SANDBOX_TIMEOUT,