Back to skill

Security audit

Robot Evolve

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a local maintenance tool, but it has under-disclosed persistent state changes and misleading safe-mode entry points that users should review before installing.

Install only if you are comfortable with a skill that can modify persistent workspace memory and store selected session content. Before use, require confirmation for MEMORY.md compression and knowledge-card generation, avoid relying on --dry-run or health_checker.py as read-only safeguards, and back up MEMORY.md first.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/auto_evolve.py:95
Finding
Destructive Memory Rewriting Without Backup or Transactional Recovery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/auto_evolve.py`, lines 95-147 **Vulnerability Type**: Destructive data handling and misleading archival behavior **Risk Level**: High ### Vulnerable Code ```python def compress_memory_if_needed(): """L1: 若MEMORY.md超过阈值,压缩并总结""" config = load_config() threshold_bytes = config.get("memory_threshold_mb", 2) * 1024 * 1024 memory_file = WORKSPACE / "MEMORY.md" if not memory_file.exists(): return ["ℹ️ MEMORY.md 不存在,跳过压缩"] size = memory_file.stat().st_size if size < threshold_bytes: return [f"ℹ️ MEMORY.md 大小 {size/1024/1024:.2f}MB,未超过阈值,跳过压缩"] # 超过阈值,读取内容进行总结 try: with open(memory_file, "r", encoding="utf-8") as f: content = f.read() # 保留前20%和最后80%的分界线 # 实际应该调用大模型API总结,但这里先做简单分割演示 lines = content.split("\n") total_lines = len(lines) # 保留最近80%的内容 keep_from = int(total_lines * 0.2) recent_content = "\n".join(lines[keep_from:]) # 生成摘要头 summary = f"""# MEMORY.md — 压缩摘要 > 由 robot-evolve 自动压缩生成 | {datetime.now().strftime('%Y-%m-%d')} ## 原始大小 - 压缩前: {size/1024/1024:.2f}MB - 行数: {total_lines} 行 ## 早期内容摘要 (详细历史请查看 `memory/evolution/` 中的归档日志) --- """ # 写入新内容 with open(memory_file, "w", encoding="utf-8") as f: f.write(summary + recent_content) new_size = memory_file.stat().st_size result = [ f"✅ MEMORY.md 已压缩(从 {size/1024/1024:.2f}MB 减少至 {new_size/1024/1024:.2f}MB)", f"✅ 保留最近 {int(total_lines * 0.8)} 行内容" ] log_action("记忆压缩", f"MEMORY.md从{size/1024/1024:.2f}MB压缩至{new_size/1024/1024:.2f}MB", "L1") return result ``` ### Technical Analysis The operation is described as compression and summarization, but it does not summarize or archive the removed material. It calculates a position at 20% of the file, retains only the rem ...[truncated 1493 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require explicit user confirmation before modifying `MEMORY.md`. 2. Write the transformed content to a temporary file in the same directory. 3. Flush and synchronize the temporary file, validate its encoding and expected content, and then use an atomic replacement operation. 4. Create a timestamped, read-only backup before replacement. 5. Archive the removed content under a dedicated memory archive, not merely an operational log directory. 6. Replace the line-deletion behavior with genuine summarization, or clearly describe it as retention-based truncation. 7. Verify that the archive exists and is readable before deleting anything from the active file. 8. Restore the backup automatically if transformation or validation fails. 9. Record hashes, byte counts, backup paths, and restoration status in the audit log. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/auto_evolve.py:304
Finding
Documented Dry-Run Mode Executes the Full Mutating Workflow<![CDATA[ ## Vulnerability Details **File Location**: `scripts/auto_evolve.py`, lines 304-323 **Vulnerability Type**: Nonfunctional safety control **Risk Level**: High ### Vulnerable Code ```python def main(): dry_run = "--dry-run" in sys.argv check_only = "--check-only" in sys.argv print("🤖 Robot-Evolve 自动进化开始") if dry_run: print("🔍 模拟模式...") if check_only: # 只做检查,不执行操作 print("🔍 检查模式(只检查,不修改)...") # 这里可以加检查逻辑 return # 执行进化 results = generate_report() # 打印报告 report_md = format_report_md(results) print("\n" + report_md) # 返回报告供调用方使用 return results ``` ### Technical Analysis The `--dry-run` argument only prints a simulation-mode message. Execution then continues directly into `generate_report()` without passing a dry-run state or suppressing side effects. The generated workflow may: - Rewrite `MEMORY.md`. - Move old items from `temp/` into `.trash`. - Create evolution logs and directories. - Read `SESSION-STATE.md`. - Create persistent knowledge files. - Add documents to a ChromaDB collection. This violates the documented expectation that dry-run mode does not perform actual modifications. It is particularly dangerous because users may select this option specifically when evaluating an unfamiliar workspace or testing whether a run is safe. ### Attack Path 1. A user invokes `python auto_evolve.py --dry-run`, expecting a simulation. 2. The program prints a message indicating simulation mode. 3. No control-flow branch prevents execution. 4. `generate_report()` invokes all normal L0/L1 operations. 5. Workspace files and persistent state may be modified exactly as in a normal run. 6. The user receives output that creates a false impression that the operation was non-mutating. ### Impact Assessment An attacker does not obtain additional operating-system privileges, but the defect bypasses a user-selected safety boundary. It allows all muta ...[truncated 179 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pass an explicit execution context, such as `dry_run=True`, into `generate_report()` and every operation it calls. 2. In dry-run mode, prohibit: - File creation or truncation. - File moves and deletions. - Directory creation. - Audit-log writes. - ChromaDB collection creation and insertion. 3. Return structured proposed actions rather than executing them. 4. Add unit tests that snapshot the filesystem before and after dry-run execution and assert that no metadata or content changes. 5. Treat unknown or unpropagated operation types as non-executable while dry-run mode is active. 6. Clearly distinguish simulated output from completed actions in the report. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/health_checker.py:14
Finding
Health-Check Entry Point Executes Destructive Evolution Operations<![CDATA[ ## Vulnerability Details **File Location**: `scripts/health_checker.py`, lines 14-22 **Vulnerability Type**: Misleading entry point and excessive side effects **Risk Level**: High ### Vulnerable Code ```python def main(): try: from auto_evolve import main as evolve_main print("=== Robot-Evolve 健康检查 ===") evolve_main() except ImportError: print("[ERROR] 无法导入 auto_evolve,请检查技能是否正确安装") sys.exit(1) except Exception as e: print(f"[ERROR] 健康检查失败: {e}") sys.exit(1) ``` ### Technical Analysis The health-check wrapper imports and invokes `auto_evolve.main()` rather than the available read-only `run_health_check()` function. Consequently, a command presented as a diagnostic operation executes the complete evolution workflow. The invoked workflow can rewrite persistent memory, move temporary files, create logs, scan other installed Skills, and persist extracted session content. These effects are unnecessary for checking workspace health and exceed the minimum privileges and side effects required by the entry point's declared purpose. This behavior also weakens the manual-trigger model because any automation or administrator invoking the health checker implicitly triggers evolution operations. ### Attack Path 1. A user, monitoring system, or package manager invokes `scripts/health_checker.py` as a diagnostic. 2. The wrapper imports `auto_evolve.main` under the name `evolve_main`. 3. It calls `evolve_main()` without a read-only argument. 4. `auto_evolve.main()` calls `generate_report()`. 5. All configured operations execute, including memory rewriting, file movement, logging, and knowledge extraction. 6. Mutations occur despite the caller requesting only a health check. ### Impact Assessment The entry point grants diagnostic callers the full mutation scope of the evolution workflow. It does not escalate to operating-system administrator privileges, but it violates least-functionality pri ...[truncated 111 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Import and call only `run_health_check()`: ```python from auto_evolve import run_health_check results = run_health_check() ``` 2. Ensure the health checker performs no writes, moves, database updates, or directory creation. 3. Separate read-only diagnostics from repair and evolution operations at the API level. 4. Require an explicit repair flag and user authorization before any mutation. 5. Add tests proving that the health checker leaves workspace contents and filesystem metadata unchanged. 6. Avoid reusing a broad entry point when a narrower function is available. ]]>

T02 · Agent Memory Poisoning

Error
Location
scripts/knowledge_manager.py:51
Finding
Session Content Is Persisted as Long-Term Knowledge Without Explicit Consent or Trust Validation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/knowledge_manager.py`, lines 51-137 **Additional Invocation Location**: `scripts/auto_evolve.py`, lines 269-276 **Vulnerability Type**: Persistent memory poisoning and sensitive-state retention **Risk Level**: High ### Vulnerable Code ```python def extract_knowledge_from_session(): """从 SESSION-STATE.md 提取知识""" if not SESSION_STATE.exists(): return [] try: with open(SESSION_STATE, "r", encoding="utf-8") as f: content = f.read() # 简单的知识提取逻辑 # 实际应该调用大模型 API,这里做基础解析 knowledge_items = [] # 检测"先生说了/先生决定/先生纠正"等模式 lines = content.split("\n") for line in lines: if any(keyword in line for keyword in ["先生", "先生说了", "先生决定", "先生纠正"]): if len(line) > 10: knowledge_items.append({ "content": line.strip(), "topic": "对话记录", "created_at": datetime.now().strftime("%Y-%m-%d"), "version": "1" }) return knowledge_items[:10] # 最多取10条 except Exception as e: print(f"提取知识失败: {e}") return [] ``` ```python def add_knowledge(client, topic, content, version="1", supersedes=None): """添加知识到向量库""" collection = get_or_create_collection(client) metadata = { "topic": topic, "version": version, "created_at": datetime.now().strftime("%Y-%m-%d"), "type": "knowledge_card" } if supersedes: metadata["supersedes"] = supersedes collection.add( documents=[content], metadatas=[metadata], ids=[f"kb_{datetime.now().strftime('%Y%m%d%H%M%S')}"] ) # 同时保存到文件库 LIBRARY_DIR.mkdir(parents=True, exist_ok=True) kb_file = LIBRARY_DIR / f"{datetime.now().strftime('%Y%m%d')}_{topic.replace(' ', '_')}.md" with open(kb_ ...[truncated 3207 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Make session-to-knowledge extraction disabled by default and require explicit, informed user consent. 2. Document exactly which session data is read, selected, retained, and used later. 3. Require the user to review and approve each proposed knowledge card before persistence. 4. Record provenance, including source file, source line, session identifier, author role, extraction time, and approval state. 5. Reject instructions, security-policy changes, credentials, secrets, quoted untrusted material, and tool output from automatic knowledge ingestion. 6. Apply secret detection and personal-data redaction before storage. 7. Treat retrieved knowledge as untrusted data rather than executable Agent instructions. 8. Add expiration, deletion, correction, and rollback mechanisms. 9. Use collision-resistant identifiers and filenames instead of overwriting cards that share a date and topic. 10. Do not invoke knowledge extraction from a health-check or dry-run path. 11. Separate ChromaDB persistence from extraction so that unavailable optional dependencies do not create ambiguous partial-state behavior. ]]>
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
  • Rogue AgentSelf-Modification, Session Persistence
Findings (24)

Ae1

High
Category
analysis-evasion
Content
| 技能目录扫描 | 扫描已安装技能,发现 `SKILL.md` 格式明显错误(如缺少名称字段)则标记并记录日志 |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Credential Access

High
Category
Privilege Escalation
Content
"id": "6",
      "name": "文件系统(工作区外)",
      "rules": [
        {"id": "6.1", "operation": "读取工作区外的公开文件(如 /etc/passwd)", "level": "L2", "note": "可能涉及敏感信息"},
        {"id": "6.2", "operation": "读取用户个人文档(桌面、文档目录)", "level": "L2", "note": "除非用户明确授权"},
        {"id": "6.3", "operation": "在工作区外创建新文件", "level": "L2", "note": "例如桌面上的临时文件"},
        {"id": "6.4", "operation": "修改或删除工作区外的任何文件", "level": "L3", "note": "用户数据红线"},
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"name": "API 密钥与环境变量",
      "rules": [
        {"id": "7.1", "operation": "读取已有的环境变量(os.getenv)", "level": "L0", "note": "仅用于技能调用"},
        {"id": "7.2", "operation": "存储用户明确提供的 API 密钥(非付费)", "level": "L0", "note": "存放位置:.env 或 openclaw.json 的 env 字段"},
        {"id": "7.3", "operation": "存储用户明确提供的付费 API 密钥", "level": "L1", "note": "如 OpenAI;提醒用户确认密钥来源可信,且不要在聊天中直接发送完整密钥"},
        {"id": "7.4", "operation": "删除或覆盖已有的 API 密钥", "level": "L2", "note": "可能导致技能失效"},
        {"id": "7.5", "operation": "将 API 密钥输出到聊天或日志", "level": "L3", "note": "绝对红线"},
Confidence
92% confidence
Finding
The policy explicitly allows storing user-provided API keys in '.env' or 'openclaw.json', and marks some key storage as L0/L1, which normalizes credential handling without requiring stronger controls such as secret isolation, encryption, redaction, or least-privilege storage. In a skill context, this is dangerous because skills often operate in shared workspaces where plaintext secrets can be read, committed, logged, or modified by other components.

Intent-Code Divergence

High
Confidence
98% confidence
Finding
The script advertises a '--dry-run' mode that should avoid modifications, but the flag only changes console output and does not prevent mutating functions from running. A user or higher-level agent relying on dry-run safety could unintentionally trigger file writes, file moves, and state changes in the workspace, which is a dangerous integrity violation.

Self-Modification

High
Category
Rogue Agent
Content
"agent"
  ],
  "keywords": [
    "self-evolve",
    "auto-evolve",
    "health-check",
    "autonomous",
Confidence
92% confidence
Finding
The skill explicitly markets ‘self-evolve’ and ‘auto-evolve’ behavior, which strongly suggests self-modification or autonomous capability expansion. In an agent context, self-modification is especially dangerous because it can bypass review assumptions, alter behavior over time, and potentially introduce unauthorized code, prompt, or configuration changes.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill explicitly authorizes automatic creation and modification of workspace files such as SOUL.md, AGENTS.md, and MEMORY.md during a trigger phrase, but the user-facing description does not provide a clear upfront warning that invoking the skill may change persistent data. This creates a consent and integrity risk: a user may expect a status check or report, yet the skill can silently alter important state files and create new content, which could be abused or cause unintended configuration drift.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The manifest’s human-readable description, notes, and operational rules are presented in Chinese throughout, which effectively imposes a single language on users and maintainers. No opt-in, language selection, or justification for a Chinese-only locale is provided in the file.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Vague Triggers

Medium
Confidence
89% confidence
Finding
The emergency-stop rule uses broad wording ('用户说停止自主进化,立即禁用所有操作') without defining scope, authority, or which actions are covered. Ambiguous control phrases in machine-consumable policy can be abused to trigger denial of service, inconsistent enforcement, or prompt-level policy confusion across unrelated tasks.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This Python file contains natural-language comments and CLI output entirely in Chinese, including usage/help text and audit messages. Because the file does not offer any language selection or explain that it is intended only for a Chinese-speaking or region-specific environment, it appears to impose a specific language without user opt-in.

Natural-Language Policy Violations

Medium
Confidence
89% confidence
Finding
The natural-language documentation and operational messaging are presented solely in Chinese, indicating a fixed language expectation without offering the user a choice or opt-in. Under the policy, forcing a specific language or locale without user selection is a natural-language policy concern.

Intent-Code Divergence

Medium
Confidence
92% confidence
Finding
The '--check-only' mode claims to perform checks without execution, but it returns immediately after printing a message and does not run the promised health or safety checks. This can mislead operators into believing validation occurred, causing unsafe assumptions and missed detection of problems before running the tool normally.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script automatically rewrites MEMORY.md once it crosses a size threshold, replacing earlier content with a generated summary and recent lines, without explicit confirmation or backup in the same operation. In an agent skill context, silent modification of a long-term memory file can cause irreversible data loss, corruption of context, or manipulation of future agent behavior.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The script automatically moves old files from the temp directory into '.trash' without warning or confirmation. Although less severe than permanent deletion, this still mutates user data and can disrupt workflows or hide files unexpectedly, particularly because the operation may occur during normal message-triggered execution.

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
The file presents itself as a health checker but actually imports and executes `auto_evolve.main()`, which is likely the skill's primary behavior rather than a minimal diagnostic. In a security-sensitive agent context, invoking the full routine during a health check can trigger unintended side effects, external actions, or state changes when callers expect a safe, read-only validation step.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The file contains user-facing strings and comments exclusively in Chinese, including the skill description and runtime status/error messages. This indicates a fixed language choice without any visible opt-in or documented locale constraint, which matches the policy category for language/locale violations.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The code adds conversation-derived text into a ChromaDB vector store without notifying the user that session content will be embedded and retained. Vector stores can preserve semantically searchable traces of sensitive conversation content, making accidental disclosure or over-retention more likely in future retrievals or database exposure incidents.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
Session-derived content from SESSION-STATE.md is persisted to disk in the knowledge library without any consent, disclosure, or filtering for sensitive data. In an agent context, conversations may contain secrets, personal data, or operational details, so silently writing them to durable storage increases the risk of privacy leakage and later unauthorized access.

Tainted flow: 'kb_file' from os.environ.get (line 129, credential/environment) → open (file write)

Medium
Category
Data Flow
Content
# 同时保存到文件库
    LIBRARY_DIR.mkdir(parents=True, exist_ok=True)
    kb_file = LIBRARY_DIR / f"{datetime.now().strftime('%Y%m%d')}_{topic.replace(' ', '_')}.md"
    with open(kb_file, "w", encoding="utf-8") as f:
        f.write(f"# 知识卡片\n\n")
        f.write(f"- **主题**: {topic}\n")
        f.write(f"- **版本**: {version}\n")
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.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The feature list advertises behaviors including temporary file cleanup, skill directory scanning, memory compression, health checks, and report pushing, all of which can affect local state or expose system information. However, the manifest does not present corresponding user warnings, scope limitations, or consent language, increasing the risk of users enabling impactful functionality without understanding what data is touched or changed.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The manifest indicates activation by a natural-language phrase like ‘执行进化’, which is broad enough to be said in ordinary conversation or quoted indirectly. Because the skill performs system- and data-affecting actions such as cleanup, scanning, and memory compression, accidental or ambiguous triggering could cause unintended execution.

Natural-Language Policy Violations

Low
Confidence
82% confidence
Finding
The natural-language instructions define activation using specific Chinese phrases such as 「执行进化」 and 「深度进化」, but the document does not offer alternate language options or indicate that the skill is intentionally limited to Chinese-speaking users. Under SQP-3, forcing a specific language without user opt-in is a policy concern.

Natural-Language Policy Violations

Low
Confidence
89% confidence
Finding
The natural-language comment at L2 is written only in Chinese and presents the file as an internal configuration without any indication that language choice is optional or region-specific. Under the policy, forcing a specific language without user opt-in can be a locale-policy violation.

Intent-Code Divergence

Low
Confidence
76% confidence
Finding
The comment at L004 frames the script as primarily a harmless recorder for post-execution notification, which suggests a narrow L1/audit role. However, the implemented logic in query_level at L054-L055 assigns unknown operations to L2 with ASK, meaning the script also serves as an authorization/classification gate rather than merely recording actions.

Static analysis

No suspicious patterns detected.