Back to skill

Security audit

Improvement Orchestrator

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed improvement orchestrator, but it can modify installed skill files and may proceed with execution even when requested evaluation fails.

Install only if you intentionally want an automated skill-improvement pipeline that can modify skill files. Use it on version-controlled targets, provide a dedicated state directory, review generated diffs, and do not rely on --task-suite as a mandatory safety gate until evaluator failures are changed to block execution.

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/orchestrate.py:189
Finding

Evaluator Failures Permit Execution Without Requested Validation

Content
View full analysis

Vulnerability Details

File Location: scripts/orchestrate.py, lines 189–201 and 403–432
Vulnerability Type: Fail-open validation / improper error handling
Risk Level: Medium

Vulnerable code:

python
try:
    artifact_path = _run_script(cmd, "evaluator")
    result = read_json(Path(artifact_path))
    evaluation = result.get("evaluation", {})
    verdict = evaluation.get("verdict", result.get("verdict", "skipped"))
    if verdict == "skipped":
        print("  Evaluator: skipped (no task suite)")
        return None
    print(f"  Evaluator: {verdict} (pass_rate={evaluation.get('execution_pass_rate', 'N/A')})")
    return result
except RuntimeError as exc:
    print(f"  Evaluator: error ({exc}), continuing without evaluation")
    return None
python
eval_result = run_evaluator(
    ranking_artifact_path,
    candidate_id,
    state_root,
    task_suite=task_suite,
    mock=eval_mock,
)
eval_verdict = eval_result.get("evaluation", {}).get("verdict") if eval_result else None
if eval_verdict == "fail":
    # Evaluation failed — treat as revert and retry
    trace = {
        "type": "evaluation_failure_trace",
        "candidate_id": candidate_id,
        "evaluation_results": eval_result.get("evaluation", {}),
        "timestamp": utc_now_iso(),
    }
    trace_dir = Path(state_root) / "traces"
    trace_dir.mkdir(parents=True, exist_ok=True)
    trace_path = trace_dir / f"eval-trace-{candidate_id}.json"
    write_json(trace_path, trace)
    active_trace = str(trace_path)
    print(f"  Evaluation failed, retrying ({attempt}/{max_retries})")
    continue

# 4. EXECUTE
execution_artifact = run_executor(
    ranking_artifact_path,
    candidate_id,
    state_root,
)

Technical Analysis

When a task suite is explicitly supplied, the evaluator is intended to validate a candidate before the executor mutates the target. However, a non-zero evaluator exit or timeout causes _run_script() to raise RuntimeError, which `run_evaluator ...[truncated 1959 chars]

Remediation
View remediation

Remediation Suggestions

  1. Treat evaluator errors as blocking whenever --task-suite is supplied. Return a distinct evaluation_error outcome or retry without invoking the executor.
  2. Require a recognized explicit verdict such as "pass" before execution. Treat missing, malformed, "skipped", and unknown verdicts as failures in mandatory-evaluation mode.
  3. Validate the evaluator artifact schema before consuming it, including the presence and permitted values of the verdict field.
  4. If fail-open behavior is operationally necessary, place it behind an explicit option such as --allow-evaluator-failure and display a prominent warning.
  5. Catch timeout and artifact-parsing failures explicitly and preserve them in a structured failure trace.
  6. Add tests proving that evaluator non-zero exits, timeouts, malformed JSON, missing verdicts, skipped verdicts, and unknown verdicts cannot reach run_executor() when a task suite was requested.

A secure decision pattern would be:

python
eval_result = run_evaluator(
    ranking_artifact_path,
    candidate_id,
    state_root,
    task_suite=task_suite,
    mock=eval_mock,
)

if task_suite:
    if not eval_result:
        final_decision = "evaluation_error"
        break

    eval_verdict = eval_result.get("evaluation", {}).get("verdict")
    if eval_verdict != "pass":
        # Record failure or invalid verdict, then retry or stop.
        continue
Vulnerability Patterns
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (13)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill clearly instructs users to run a shell-based orchestration script that reads and writes target skill directories, yet it declares no explicit tool scope or permissions. In an agent environment, this omission can lead to over-broad implicit access, making unintended file modification or command execution more likely when the orchestrator is invoked on arbitrary paths.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest description is entirely in Chinese, which imposes a specific language on users without any opt-in or alternative language path. The policy for natural-language violations applies to all file types, and there is no indication that this skill is intentionally region-specific or that users may choose their preferred language.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The example and anti-example sections present core usage instructions only in Chinese, which effectively constrains the skill's operational documentation to one language. Because no language choice or justified locale restriction is documented, this is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This markdown file is written almost entirely in Chinese, including headings, instructions, command explanations, and decision descriptions, with no indication that another language is supported or that the user can opt into Chinese. Under the policy for natural-language violations, forcing a specific language without user choice is reportable unless the locale constraint is clearly documented and justified.

Content

No source excerpt is available for this finding.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · references/end-to-end-demo.md (reported line 83)May include surrounding context.

md
{
      "id": "cand-001",
      "title": "添加行业特定模板章节",
      "target_path": "$OPENCLAW_ROOT/workspace/skills/newsletter-creation-curation/SKILL.md",
      "category": "reference",
      "rationale": "用户反馈缺少行业模板,补充后可提升技能实用性",
      "risk_level": "low",

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · references/end-to-end-demo.md (reported line 106)May include surrounding context.

md
{
      "id": "cand-001",
      "title": "添加行业特定模板章节",
      "target_path": "$OPENCLAW_ROOT/workspace/skills/newsletter-creation-curation/SKILL.md",
      "category": "reference",
      "rationale": "用户反馈缺少行业模板,补充后可提升技能实用性",
      "risk_level": "low",

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · references/end-to-end-demo.md (reported line 245)May include surrounding context.

md
{
      "id": "cand-001",
      "title": "添加行业特定模板章节",
      "target_path": "$OPENCLAW_ROOT/workspace/skills/newsletter-creation-curation/SKILL.md",
      "category": "reference",
      "rationale": "用户反馈缺少行业模板,补充后可提升技能实用性",
      "risk_level": "low",

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · references/end-to-end-demo.md (reported line 258)May include surrounding context.

md
{
      "id": "cand-001",
      "title": "添加行业特定模板章节",
      "target_path": "$OPENCLAW_ROOT/workspace/skills/newsletter-creation-curation/SKILL.md",
      "category": "reference",
      "rationale": "用户反馈缺少行业模板,补充后可提升技能实用性",
      "risk_level": "low",

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This section documents automatic execution, file modification, backup, rollback, and state-file writes, but it does not clearly foreground that running the workflow can change skill files on disk. Users may invoke the orchestrator expecting analysis only, when it can persist modifications and state transitions automatically, creating integrity and surprise-change risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The file's natural-language content is overwhelmingly in Chinese, including operational instructions and policy descriptions, with no indication that users may choose another language or that the Chinese-only presentation is required for a region-specific purpose. This can violate a language/locale policy requiring user opt-in or documented justification for a forced language.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This markdown file is written almost entirely in Chinese, including headings, instructions, and operational notes, with no indication that the language is optional or that the skill is specifically intended for a Chinese-speaking or region-specific context. Under the stated policy, forcing a specific language without user opt-in can be a natural-language policy violation.

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

python
Raises RuntimeError on non-zero exit.
    """
    result = subprocess.run(cmd, capture_output=True, text=True, timeout=1200)
    if result.returncode != 0:
        raise RuntimeError(
            f"{label} failed (exit {result.returncode}):\n"

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

python
Raises RuntimeError on non-zero exit.
    """
    result = subprocess.run(cmd, capture_output=True, text=True, timeout=1200)
    if result.returncode != 0:
        raise RuntimeError(
            f"{label} failed (exit {result.returncode}):\n"

Static analysis

No suspicious patterns detected.