Back to skill

Security audit

Meta-Harness Evolver

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed meta-evolution tool, but it gives automated sub-agents high-impact authority over core agent configuration and can send unsanitized internal reasoning to Discord.

Install only if you are comfortable with an automated experiment modifying core OpenClaw/Hoss behavior. Run it in an isolated test workspace first, remove or redact secrets from TOOLS.md and proposer traces, disable Discord posting unless explicitly needed, and require human review before promoting any candidate into a live agent workspace.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T01 · Skill Instruction Hijacking

Error
Location
scripts/run_evolution.py:86
Finding

Autonomous Modification of Core Agent Instructions

Content
View full analysis
Write reasoning to ~/hoss-evolution/candidates/candidat ...[truncated 2559 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/evaluate.py:325
Finding

Unsafe Candidate Deployment Can Leave Unauthorized Files and Instructions in the Live Workspace

Content
View full analysis
bool: """Apply candidate harness to Hoss workspace (for evaluation).""" harness_dir = candidate_dir / "harness" if not harness_dir.exists(): print(f"[EVAL] No harness directory found") return False # Backup current configs backup_dir = candidate_dir / "backup" backup_dir.mkdir(exist_ok=True) for fname in ["SOUL.md", "IDENTITY.md", "AGENTS.md", "TOOLS.md", "HEARTBEAT.md"]: src = HOSS_WORKSPACE / fname if src.exists(): shutil.copy2(src, backup_dir / fname) # Apply candidate harness for f in harness_dir.iterdir(): shutil.copy2(f, HOSS_WORKSPACE / f.name) return True def restore_harness(candidate_dir: Path): """Restore the backed-up harness after evaluation.""" backup_dir = candidate_dir / "backup" if not backup_dir.exists(): return for f in backup_dir.iterdir(): shutil.copy2(f, HOSS_WORKSPACE / f.name) ``` ### Technical Analysis The deployment loop copies every entry in the candidate harness directory into `~/.openclaw/workspace/`. It does not enforce the documented filename allowlist, verify that entries are regular files, reject symbolic links, validate canonical paths, or restrict file types. The rollback mechanism restores only files present in the backup directory. If the candidate introduces a new file that did not previously exist, restoration does not remove it. Candidate application and restoration are also not protected by a `try/finally` block. An exception during scoring or restoration can therefore leave modified candidate files active. The live operational workspace is used as an evaluation environment even though a disposable copy would be sufficient for the implemented ...[truncated 1125 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/evaluate.py:352
Finding

Trivially Gameable Benchmark Can Promote Unsafe Harnesses as the Best Candidate

Content
View full analysis
int: """ Run a single scenario against the candidate harness. Returns score 0-3 based on rubric. """ print(f"\n[EVAL] Running: {scenario['id']} — {scenario['name']}") # Apply harness candidate_dir = harness_dir.parent apply_harness(candidate_dir) # Simulate evaluation — in production this would actually run Hoss on the task # For now, we do a heuristic evaluation based on the harness files score = 1 # default partial pass # Check harness complexity and quality signals soul_file = harness_dir / "SOUL.md" if soul_file.exists(): content = soul_file.read_text() # Better SOUL.md = more complete personality guidance if len(content) > 500 and "##" in content: score = max(score, 2) if "boundaries" in content.lower() or "red lines" in content.lower(): score = max(score, 2) if "co-founder" in content.lower(): score = max(score, 3) # Check TOOLS.md quality tools_file = harness_dir / "TOOLS.md" if tools_file.exists(): content = tools_file.read_text() if "##" in content and len(content) > 300: score = max(score, 2) # Restore original harness restore_harness(candidate_dir) print(f"[EVAL] {scenario['id']}: score={score}/3") return score ``` ### Technical Analysis The evaluator does not execute any scenario task or evaluate scenario-specific outcomes. Instead, all memory, code, coordination, research, communication, and quality scenarios use the same file-length and keyword heuristic. In particular, the presence of the string `co-founder` in `SOUL.md` raises every scenario to the maximum score of ...[truncated 1327 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/post_to_research.py:48
Finding

Untrusted Proposer Reasoning Is Sent to an External Discord Channel Without Secret Filtering

Content
View full analysis
str: """Read the proposer's reasoning trace.""" reasoning_file = candidate_dir / "proposer_reasoning.md" if reasoning_file.exists(): content = reasoning_file.read_text() # Truncate if too long if len(content) > 500: return content[:500] + "..." return content return "No reasoning trace found." ``` ```python def build_message(candidate_num: int, candidate_dir: Path, score: float, proposer_ok: bool) -> str: """Build the Discord message.""" best_score = get_best_score() delta = score - best_score delta_str = f"+{delta:.1f}" if delta > 0 else f"{delta:.1f}" history = get_history_summary() reasoning = get_proposer_reasoning(candidate_dir) changes = get_change_summary(candidate_dir) candidate_dir = Path(candidate_dir) emoji = "🔺" if delta > 0 else "🔻" if delta < 0 else "➡️" status = "NEW BEST!" if score > best_score else "no change" if score == best_score else f"{delta_str} vs best" msg = f"""**⚡ Meta-Harness Evolution — Nightly Report** **Candidate:** `candidate_{candidate_num}` **Score:** `{score}/100` {emoji} {status} **Proposer:** {"✅ Success" if proposer_ok else "❌ Failed"} --- **What Changed:** {changes} --- **Proposer's Reasoning:** {reasoning} --- **Recent History:** {history} --- _Posted {datetime.now().strftime("%Y-%m-%d %H:%M:%S")} CDT_""" return msg ``` ```python # Actually send via openclaw import subprocess result = subprocess.run( ["openclaw", "message", "--channel", "discord", "--target", DISCORD_CHANNEL_ID, "--message", message], capture_output=True, text=True, timeout=30, ) ``` ### Technical Analysis The proposer reasoning file ...[truncated 1733 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

This mismatch indicates the skill may operate on persisted 'best/current' snapshots rather than the live workspace it claims to analyze, and it also persists winner state not clearly disclosed. That can mislead operators about what data is being used and changed, causing unsafe assumptions, stale-config evaluation, or unnoticed stateful drift across runs.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

This mismatch indicates the skill may operate on persisted 'best/current' snapshots rather than the live workspace it claims to analyze, and it also persists winner state not clearly disclosed. That can mislead operators about what data is being used and changed, causing unsafe assumptions, stale-config evaluation, or unnoticed stateful drift across runs.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The initialization steps seed HEARTBEAT.md but omit MEMORY.md, contradicting the described source-of-truth set for evolution. In an automated nightly system that mutates agent control files, this scope mismatch can cause unintended persistence or modification of a control file outside the advertised boundary, undermining operator expectations and review coverage.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · references/harness-spec.md (reported line 48)May include surrounding context.

md
### HEARTBEAT.md — Active Hours & Checks
**Path:** `~/.openclaw/workspace/HEARTBEAT.md`
**What it controls:** Active hours (8 AM - 10 PM CDT), skip conditions, batched checks (git backup, memory health, cron health), sub-agent health monitoring, output rules
**Can evolve:** Yes — check priorities, thresholds, active hours, what gets checked
**Do NOT change:** URGENT designation logic

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill describes filesystem reads/writes and shell-based execution but does not declare an explicit tool scope or permission boundary. In an agent environment, missing least-privilege constraints can allow broader-than-necessary file and command access, increasing the blast radius if the skill is misused or the proposer/evaluator handles sensitive workspace content unsafely.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

Posting benchmark summaries to Discord is an external data transfer channel, yet the skill text does not prominently warn that workspace-derived information, traces, or performance details may leave the local environment. In this context, the skill reads agent configs and evaluation traces, so even summaries can leak sensitive operational details or indirectly expose secrets-bearing content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill states that candidate harnesses, scores, and execution traces are stored long-term under ~/hoss-evolution/ but does not warn about retention of potentially sensitive agent data. Because the system reads core agent configs and logs proposer reasoning/traces, persistent storage can accumulate secrets, internal prompts, and operational context that become valuable if the host or directory is later accessed.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest description limits the skill's inputs to SOUL.md, IDENTITY.md, AGENTS.md, TOOLS.md, and MEMORY.md. This file documents proposer behavior that diagnoses and proposes edits to HEARTBEAT.md, and initialization also copies HEARTBEAT.md into the harness seed. That is a semantic expansion of the described harness scope.

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 · references/evolution-logic.md (reported line 109)May include surrounding context.

md
## When Proposals Fail

Common failure modes:
1. **Too ambitious** — proposer tries to rewrite everything → incoherent harness
2. **False pattern** — proposer sees correlation that isn't causal → wrong fix
3. **Benchmark gaming** — proposer overfits to specific scenario wording
4. **Discontinuity** — big change breaks something unrelated

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module docstring says the script evaluates a candidate harness against 20 benchmark scenarios and computes scores from those scenario outcomes. In practice, run_scenario does not execute the scenario tasks at all; it assigns scores based largely on superficial properties of SOUL.md and TOOLS.md content, which contradicts the stated evaluation behavior.

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 · scripts/evaluate.py (reported line 78)May include surrounding context.

python
"id": "code_1",
        "category": "code",
        "weight": 0.10,
        "name": "Write a working Python script",
        "task": "Write a Python script that: 1) reads ~/hoss-evolution/evolution_log.jsonl, 2) finds the candidate with the highest final_score, 3) prints the candidate name and score. Make it executable and working.",
        "expected": "Script runs without error, correctly identifies best candidate",
        "rubric": {

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The function and surrounding flow imply that the candidate harness is applied so the benchmark can evaluate actual agent behavior. However, lines L363-L365 explicitly state the script only performs heuristic evaluation based on harness files, so the operational comments overstate what the evaluation does.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The evaluator copies every file from an untrusted candidate harness directly into the live Hoss workspace, modifying active configuration without validation, approval, or sandboxing. In this skill context, harness files define agent behavior and tool usage, so a malicious candidate could persistently alter the agent's instructions, permissions, or integrations and affect later runs beyond the evaluation itself.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script summarizes entries from evolution_log.jsonl and posts them to Discord without checking whether those logs contain sensitive experiment metadata or user-derived content. Because this skill runs on an automated nightly pipeline over agent workspace artifacts, the context increases the risk that internal benchmark outcomes or other sensitive operational details are exfiltrated to an external service.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script reads proposer_reasoning.md and automatically includes its contents in an outbound Discord message with only length truncation, not sensitivity filtering. In this skill context, proposer reasoning may contain secrets, system prompts, internal workspace content, or attacker-influenced text from harness evolution artifacts, so posting it externally can leak sensitive data.

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/post_to_research.py (reported line 158)May include surrounding context.

python
# Actually send via openclaw
    import subprocess
    result = subprocess.run(
        ["openclaw", "message", "--channel", "discord",
         "--target", DISCORD_CHANNEL_ID, "--message", message],
        capture_output=True,

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/run_evolution.py (reported line 177)May include surrounding context.

python
print(f"[EVALUATE] Running benchmark for {candidate_dir.name}...")
    eval_script = SCRIPTS_DIR / "evaluate.py"

    result = subprocess.run(
        [sys.executable, str(eval_script), str(candidate_dir)],
        capture_output=True,
        text=True,

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/run_evolution.py (reported line 252)May include surrounding context.

python
print("[DISCORD] Posting to #research...")
    post_script = SCRIPTS_DIR / "post_to_research.py"

    result = subprocess.run(
        [sys.executable, str(post_script), str(candidate_num), str(candidate_dir),
         str(scores.get("final_score", 0)), str(int(proposer_ok))],
        capture_output=True,

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The evaluator creates a backup directory inside the provided candidate directory and writes copies of several workspace files into it. While this supports restoration, the code does not clearly warn the user that running the evaluator will create and populate a backup directory under the candidate path.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.