Back to skill

Security audit

Apollo Coordinator

Security checks for vulnerabilities and agentic risk

Overview

This skill is a local multi-agent coordination guide with a support status-check script; it has some under-disclosed local state handling but no evidence of exfiltration, destructive behavior, or deception.

Install only if you want a Chinese-language coordinator workflow and are comfortable with a local status script reading OpenClaw workflow/task metadata and writing coordinator state. The publisher should document the script behavior and fix JSON-safe output generation.

Vulnerability Patterns
  • 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
  • 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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/coordinator/coordinator-check.sh:126
Finding
Unescaped Workflow Data Allows JSON State Injection<![CDATA[ ## Vulnerability Details **File Location**: `scripts/coordinator/coordinator-check.sh`, source at line 14 and vulnerable output construction at lines 126–136 **Vulnerability Type**: Improper escaping when generating JSON **Risk Level**: Medium ### Vulnerable Code ```bash check_workflow() { if [ -f "$WORKFLOW_DIR/state.json" ]; then python3 -c "import json; d=json.load(open('$WORKFLOW_DIR/state.json')); print(d.get('phase', 'unknown'))" 2>/dev/null || echo "error" else echo "no_workflow" fi } ``` The resulting value is inserted directly into a JSON heredoc: ```bash cat > "$STATE_FILE" << EOF { "workflow": "$workflow", "gates_passed": $passed, "gates_total": $total, "skills_with_check": $with_check, "skills_with_version": $with_version, "skills_total": $skill_total, "pending_tasks": $pending, "score": $score, "checked_at": "$(date -Iseconds)" } EOF ``` ### Technical Analysis The `phase` property is read from `/root/.openclaw/workspace/.workflow/state.json` and printed as raw text. The script subsequently places that text inside a quoted JSON value without applying JSON escaping. A `phase` value containing quotation marks, backslashes, control characters, or newlines can therefore break out of the intended `workflow` string. This can inject additional properties into the generated `.coordinator/state.json` file or make the file invalid. For example, a valid source JSON document could contain a value logically equivalent to: ```json { "phase": "ok\",\n \"forged_state\": true,\n \"padding\": \"" } ``` When interpolated by the heredoc, this introduces attacker-selected structure into the generated status document. This is a data-integrity vulnerability rather than shell command injection: shell metacharacters resulting from variable expansion are not reparsed as shell syntax. ### Attack Path 1. An attacker or compromised component obtains permission to modify `/root/.opencl ...[truncated 1379 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Generate the output document with a JSON-aware serializer instead of interpolating values into a heredoc. For example, pass the collected values as arguments to Python and use `json.dump`: ```bash python3 - "$STATE_FILE" "$workflow" "$passed" "$total" \ "$with_check" "$with_version" "$skill_total" "$pending" "$score" <<'PY' import datetime import json import sys ( output_file, workflow, passed, total, with_check, with_version, skill_total, pending, score, ) = sys.argv[1:] document = { "workflow": workflow, "gates_passed": int(passed), "gates_total": int(total), "skills_with_check": int(with_check), "skills_with_version": int(with_version), "skills_total": int(skill_total), "pending_tasks": int(pending), "score": int(score), "checked_at": datetime.datetime.now( datetime.timezone.utc ).astimezone().isoformat(), } with open(output_file, "w", encoding="utf-8") as stream: json.dump(document, stream, ensure_ascii=False, indent=4) stream.write("\n") PY ``` Additional hardening measures should include: 1. Validate that `phase` is a string and, if the accepted states are known, enforce an allowlist such as `pending`, `running`, `complete`, and `failed`. 2. Reject unexpected control characters and impose a reasonable maximum length. 3. Write to a securely created temporary file in the destination directory and atomically rename it to prevent readers from observing partial output. 4. Apply restrictive permissions to the state directory and files so untrusted users cannot modify workflow input or replace coordinator output. 5. Add tests using phase values containing quotes, backslashes, newlines, Unicode characters, and other JSON boundary cases. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
声明描述的是一个“把复杂任务交给多个小助手同时做并汇总结果”的协调执行能力。但实际代码是一个状态检测脚本:检查 workflow phase、gate 文件通过情况、skills 是否有 check/version、待处理任务数量,并生成状态报告保存到 state.json。虽然名称和输出文案与“coordinator”有关,但它并不实际创建、分发、协调或汇总多个助手的工作结果。其主要目的与声明存在实质偏差,且还进行了未在声明中体现的本地状态文件读写。因此应判定为描述与行为不匹配。

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The skill’s natural-language description is written as a Chinese-only user-facing instruction and does not indicate that users may choose another language or locale. Under the stated policy, forcing a specific language without opt-in is a language/locale policy violation.

Vague Triggers

Medium
Confidence
87% confidence
Finding
The trigger phrases are broad and have no stated exclusion conditions, so the skill could activate in contexts where a user merely mentions task decomposition or multi-agent coordination conceptually. Unintended invocation can route user requests into unnecessary orchestration flows, increasing the chance of confusion, incorrect delegation, or accidental processing of tasks that should remain single-agent.

Static analysis

No suspicious patterns detected.