High Risk — Risk Score 67/100
Last scan:1 day ago Rescan
67 /100
mind-wander
Autonomous background reasoning agent that explores open questions using a local LLM, FalkorDB knowledge graph, and Perplexity web search
SKILL.md documents a read-only reasoning agent but the actual implementation contains undeclared arbitrary Python code execution (sandbox_run), filesystem writes (elevate, DEAD_ENDS.md), external network requests, and system cron registration — a significant doc-to-code mismatch.
Skill Namemind-wander
Duration83.1s
Enginepi
Do not install this skill
Do not use until SKILL.md is updated to accurately declare all tool capabilities (sandbox_run, elevate, search_web, FalkorDB access, cron registration). sandbox_run() is particularly dangerous as it bypasses the stated no-network sandbox claim through Python exec with weak string-based blocking.

Attack Chain 6 steps

Entry User installs skill expecting a read-only background reasoning agent from SKILL.md
SKILL.md:1
Escalation install.sh runs automatically, installing pip packages, registering a 30-min cron job, and reading ~/.openclaw/openclaw.json for tokens
scripts/install.sh:70
Escalation sandbox_run() executes arbitrary Python code via subprocess.run(['python3', '-c', ...]) — bypasses weak BLOCKED-list string checks
scripts/tools.py:310
Escalation read_file() and elevate() write arbitrary content to workspace files (MENTAL_EXPLORATION.md, DEAD_ENDS.md, state.json)
scripts/tools.py:358
Impact search_web() exfiltrates workspace content via Perplexity API calls using the user's API key
scripts/tools.py:130
Impact Cron persistence reinstalls on each run via gateway API — survives skill 'uninstall' if gateway token remains
scripts/install.sh:151

Findings 9 items

Severity Finding Location
High
Undeclared arbitrary Python code execution via sandbox_run() RCE
sandbox_run() in tools.py executes arbitrary Python code passed by the LLM agent via subprocess.run(['python3', '-c', safe_code]). The BLOCKED-list is a simple string-inclusion check easily bypassed. This capability is entirely absent from SKILL.md's tool table.
result = subprocess.run(['python3', '-c', safe_code], capture_output=True, text=True, timeout=SANDBOX_TIMEOUT)
→ Declare sandbox_run() explicitly in SKILL.md. Consider stronger sandboxing (namespace sandboxing, seccomp, Docker) or restrict to a curated safe-eval whitelist of mathematical/scientific operations only.
scripts/tools.py:310
High
SKILL.md tool table omits 4 of 8 tools Doc Mismatch
SKILL.md declares 7 tools (query_graph, search_web, read_file, list_files, sandbox_run, check_dead_ends, record_dead_end, elevate) but the tool table only lists 7 items. Actually all 7 are in the registry, but elevate() and the filesystem WRITE operations are missing from the capability declarations. More critically, the network:WRITE, shell:WRITE, database:READ+WRITE, and persistence capabilities are not declared at all.
SKILL.md declares 'network:READ via WebFetch' in the capability model header but never mentions that search_web() POSTs API keys and queries to an external endpoint
→ Update SKILL.md to accurately declare all 8 resource-level capabilities (filesystem:READ+WRITE, shell:WRITE, network:READ+WRITE, database:READ+WRITE, persistence:WRITE).
SKILL.md:1
High
Undeclared cron job registration on install Persistence
install.sh silently registers a 30-minute cron job via the OpenClaw gateway API, embedding Python code as a string in the message payload. This persistence mechanism is not mentioned anywhere in SKILL.md.
httpx.post(f'http://localhost:{port}/api/cron/jobs', headers={'Authorization': f'Bearer {token}'}, json=job)
→ Declare cron registration in SKILL.md. Make the cron job registration explicit and user-visible rather than automatic.
scripts/install.sh:151
High
Undeclared credential file access Sensitive Access
search_web() reads ~/.openclaw/openclaw.json to extract the Perplexity API key as a fallback. The cron registration code also reads this file for the gateway auth token. This credential access is not declared.
config_path = Path.home() / '.openclaw' / 'openclaw.json'; cfg = json.load(f); api_key = cfg.get('plugins', {}).get('entries', {}).get('perplexity', {})...
→ Declare ~/.openclaw/openclaw.json access in SKILL.md. Document what fields are read and why. Consider using environment variables or a dedicated secrets store instead.
scripts/tools.py:137
Medium
Weak sandbox BLOCKED-list trivially bypassed Obfuscation
sandbox_run() uses simple string-inclusion checks against a BLOCKED list (e.g., 'exec(', 'eval(', '__import__', 'ctypes'). These can be bypassed via string concatenation, formatting, or base64. The sandbox also lacks resource limits beyond a timeout.
for blocked in BLOCKED: if blocked in code: return {'ok': False, ...}
→ Use AST-based parsing to detect dangerous patterns, or whitelist allowed operations. Consider running in a Docker container or gVisor for true isolation.
scripts/tools.py:302
Medium
Unpinned pip dependencies in install.sh Supply Chain
install.sh installs huggingface_hub, httpx, falkordb, numpy without version pins. This could pull different (potentially vulnerable) versions on re-run.
pip3 install --user --break-system-packages --quiet huggingface_hub httpx falkordb numpy
→ Pin all dependencies to specific versions. Use a requirements.txt or lock file.
scripts/install.sh:77
Medium
Third-party model download from HuggingFace Supply Chain
The skill downloads a Qwen3.5 GGUF model from a third-party HuggingFace repo (Jackrong/Qwen3.5-9B-Claude-4.6-Opus-Reasoning-Distilled-v2-GGUF) which is not an official Qwen release. Model could be modified.
repo_id='Jackrong/Qwen3.5-9B-Claude-4.6-Opus-Reasoning-Distilled-v2-GGUF'
→ Document that a third-party distilled model is used. Consider verifying the model's integrity or using an official Qwen repository.
scripts/install.sh:99
Low
Hardcoded internal IP addresses expose infrastructure Priv Escalation
172.18.0.1 is hardcoded in SKILL.md, mind_wander_config.py, and install.sh as the Ollama and FalkorDB endpoint. This exposes Docker/internal network topology.
WANDER_OLLAMA = 'http://172.18.0.1:11436'
→ Use environment variables for all connection endpoints. Document expected network topology without exposing specific IPs.
SKILL.md:111
Low
Skill description overstates local-only nature Doc Mismatch
SKILL.md says 'Runs locally on Qwen3.5-9B, consumes zero Anthropic tokens' but the skill makes API calls to api.perplexity.ai (external, paid), Ollama at a specific IP, and FalkorDB at a specific IP.
'Runs locally on Qwen3.5-9B, consumes zero Anthropic tokens' — omits Perplexity API cost and network dependencies
→ Update description to accurately reflect external service dependencies.
SKILL.md:10
ResourceDeclaredInferredStatusEvidence
Filesystem READ WRITE ✗ Violation scripts/tools.py:elevate() writes MENTAL_EXPLORATION.md; scripts/wander_graph.py…
Shell NONE WRITE ✗ Violation scripts/tools.py:sandbox_run() → subprocess.run(['python3', '-c', safe_code]) ex…
Network NONE READ+WRITE ✗ Violation scripts/tools.py:search_web() POSTs to api.perplexity.ai; scripts/wander_graph.p…
Database NONE READ+WRITE ✗ Violation scripts/tools.py:query_graph() reads/writes FalkorDB 'workspace' graph; scripts/…
Environment NONE READ ✗ Violation scripts/tools.py:search_web() reads ~/.openclaw/openclaw.json for API key; scrip…
Skill Invoke NONE WRITE ✗ Violation scripts/install.sh registers cron jobs via gateway API; SKILL.md does not mentio…
1 High 7 findings
📡
High IP Address 硬编码 IP 地址
172.18.0.1
SKILL.md:111
🔗
Medium External URL 外部 URL
http://172.18.0.1:11436
SKILL.md:111
🔗
Medium External URL 外部 URL
https://doi.org/10.1038/nrn.2016.113
references/research.md:21
🔗
Medium External URL 外部 URL
https://doi.org/10.1038/nrn1607
references/research.md:27
🔗
Medium External URL 外部 URL
https://arxiv.org/abs/2409.02685
references/research.md:33
🔗
Medium External URL 外部 URL
https://bootstrap.pypa.io/get-pip.py
scripts/install.sh:75
🔗
Medium External URL 外部 URL
https://api.perplexity.ai/chat/completions
scripts/tools.py:130

File Tree

11 files · 81.2 KB · 2167 lines
Python 7f · 1654L Markdown 3f · 301L Shell 1f · 212L
├─ 📁 references
│ ├─ 📝 research.md Markdown 64L · 3.2 KB
│ └─ 📝 setup.md Markdown 105L · 3.0 KB
├─ 📁 scripts
│ ├─ 🐍 agent.py Python 315L · 11.9 KB
│ ├─ 🐍 collector.py Python 94L · 3.0 KB
│ ├─ 🔧 install.sh Shell 212L · 7.7 KB
│ ├─ 🐍 mind_wander_config.py Python 49L · 3.1 KB
│ ├─ 🐍 prompt.py Python 132L · 5.5 KB
│ ├─ 🐍 run.py Python 150L · 5.6 KB
│ ├─ 🐍 tools.py Python 622L · 23.6 KB
│ └─ 🐍 wander_graph.py Python 292L · 9.8 KB
└─ 📝 SKILL.md Markdown 132L · 4.8 KB

Dependencies 5 items

PackageVersionSourceKnown VulnsNotes
huggingface_hub * pip No Version not pinned in install.sh
httpx * pip No Version not pinned in install.sh
falkordb * pip No Version not pinned in install.sh
numpy * pip No Version not pinned in install.sh
Jackrong/Qwen3.5-9B-Claude-4.6-Opus-Reasoning-Distilled-v2-GGUF unknown HuggingFace third-party No Third-party model repo, not official Qwen — integrity not verifiable

Security Positives

✓ sandbox_run() has a timeout (30s) and line limit (50 lines) — some resource controls exist
✓ sandbox_run() blocks some dangerous imports (subprocess, socket, urllib, requests, httpx, eval, exec, __import__) — at least a basic denylist is present
✓ read_file() has a workspace boundary check to prevent path traversal
✓ The novelty gate (strict criteria for elevate()) means most outputs are benign — findings written to a markdown file
✓ Dead ends are tracked to avoid redundant exploration — reduces unnecessary file writes
✓ SKILL.md exists and provides a reasonable description of the high-level concept
✓ Code is well-structured with docstrings explaining each function's purpose
✓ Uses standard, well-known libraries (httpx, falkordb) rather than obscure custom crypto