Back to skill

Security audit

Learning Loop - GEARS System

Security checks for vulnerabilities and agentic risk

Overview

The skill is a disclosed autonomous learning scheduler, but it gives agents durable cron-job authority and can continue creating future sessions with limited later user control.

Review before installing. This skill is not just a study helper: it creates local learning files and modifies OpenClaw cron jobs so agents keep running later. Use it only if you want recurring autonomous sessions, inspect ~/.openclaw/cron/jobs.json after setup, and prefer explicit topic slugs and clear stop/pause instructions.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/create_pipeline.sh:8
Finding

Unvalidated Topic Slug Permits Path Traversal and Out-of-Scope File Creation

Content
View full analysis

Vulnerability Details

File Location: scripts/create_pipeline.sh, lines 8-28
Vulnerability Type: Path traversal through an unvalidated filesystem path component
Risk Level: High

Vulnerable Code

bash
TOPIC_SLUG="${1:?Usage: $0 <topic-slug> [topic-display-name]}"
TOPIC_NAME="${2:-$TOPIC_SLUG}"

# Resolve workspace-relative path
WORKSPACE="${OPENCLAW_WORKSPACE:-$HOME/.openclaw/workspace}"
BASE_DIR="${WORKSPACE}/memory/learning/${TOPIC_SLUG}"

if [ -d "$BASE_DIR" ]; then
    echo "Error: Topic directory already exists: $BASE_DIR"
    echo "Remove it first or choose a different slug."
    exit 1
fi

# Create directory structure
mkdir -p "${BASE_DIR}/sessions"
mkdir -p "${BASE_DIR}/knowledge"

# Create initial state.json
NOW=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
cat > "${BASE_DIR}/state.json" << EOF

Technical Analysis

TOPIC_SLUG is accepted directly from the first command-line argument and appended to the intended learning directory without validation or canonical-path containment verification. Shell quoting prevents word splitting and wildcard expansion, but it does not neutralize path traversal sequences such as ../.

The documentation instructs the agent to generate a slug, but the executable script does not enforce that requirement. A caller can therefore supply traversal components that cause BASE_DIR to resolve outside ${WORKSPACE}/memory/learning.

The existing-directory check only prevents use of a final path that already exists. It does not prevent creation of a new attacker-selected directory outside the intended location.

Attack Path

  1. An attacker or untrusted caller invokes create_pipeline.sh with a crafted topic slug containing enough ../ components to escape memory/learning.
  2. The script constructs BASE_DIR by concatenating the untrusted value to the workspace path.
  3. The operating system resolves the traversal components when ...[truncated 1404 chars]
Remediation
View remediation

Remediation Suggestions

  1. Enforce a strict slug allowlist before constructing any path:

    bash
    if [[ ! "$TOPIC_SLUG" =~ ^[a-z0-9]+(-[a-z0-9]+)*$ ]]; then
        echo "Error: topic slug must contain only lowercase letters, digits, and single hyphen separators." >&2
        exit 1
    fi
    
  2. Canonicalize both the learning root and candidate destination, then verify containment before writing.

  3. Reject slashes, backslashes, . components, .. components, control characters, and empty values.

  4. Validate OPENCLAW_WORKSPACE as an absolute, trusted directory or derive it from trusted configuration rather than arbitrary inherited environment data.

  5. Create files using restrictive permissions, such as umask 077, if pipeline state may contain private learning or notification information.

  6. Add regression tests for ../, absolute-looking paths, repeated separators, control characters, and symbolic-link edge cases.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/create_pipeline.sh:8
Finding

Unescaped User Input Is Interpolated Directly into JSON State

Content
View full analysis

Vulnerability Details

File Location: scripts/create_pipeline.sh, lines 8-9 and 25-31
Vulnerability Type: JSON injection and malformed state generation
Risk Level: Medium

Vulnerable Code

bash
TOPIC_SLUG="${1:?Usage: $0 <topic-slug> [topic-display-name]}"
TOPIC_NAME="${2:-$TOPIC_SLUG}"

# Create initial state.json
NOW=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
cat > "${BASE_DIR}/state.json" << EOF
{
  "topic": "${TOPIC_NAME}",
  "topicSlug": "${TOPIC_SLUG}",
  "phase": 1,

Technical Analysis

TOPIC_NAME and TOPIC_SLUG are inserted directly into a JSON document through an interpolated heredoc. Shell quoting at assignment time does not perform JSON string escaping.

Characters with special meaning in JSON—including double quotes, backslashes, newlines, carriage returns, tabs, and other control characters—can therefore terminate a string, introduce additional syntax, or render the document invalid.

Later autonomous sessions treat state.json as the pipeline's control state. A malformed document causes parsers such as json.load to fail. Crafted valid JSON may also introduce unexpected properties, although the effect of any injected property depends on how subsequent agents and tools interpret the state.

Attack Path

  1. A caller supplies a display name or topic slug containing JSON metacharacters.
  2. The script substitutes the value verbatim inside a quoted JSON string.
  3. The generated state.json becomes malformed or structurally different from the intended schema.
  4. check_progress.sh or a scheduled learning agent attempts to parse the state.
  5. Parsing fails, or the autonomous workflow processes unexpected state, disrupting pipeline execution.

For example, a display name containing an unescaped double quote is sufficient to produce invalid JSON:

bash
bash scripts/create_pipeline.sh safe-slug 'Invalid " Topic'

The resulting fragment contains a ...[truncated 646 chars]

Remediation
View remediation

Remediation Suggestions

  1. Generate JSON with a real JSON serializer instead of interpolating values into a heredoc. For example:

    bash
    python3 - "$BASE_DIR/state.json" "$TOPIC_NAME" "$TOPIC_SLUG" "$NOW" <<'PY'
    import json
    import sys
    
    output, topic, slug, now = sys.argv[1:]
    state = {
        "topic": topic,
        "topicSlug": slug,
        "phase": 1,
        "curriculum": [],
        "currentSubtopicIndex": 0,
        "currentDay": 1,
        "currentSession": "S1",
        "status": "in_progress",
        "sessionTiming": {
            "dailyStartHour": 9,
            "s1ToS2Hours": 4,
            "s2ToS3Hours": 4,
            "s3ToS4Hours": 4
        },
        "notifications": {
            "deliver": False,
            "channel": None,
            "to": None
        },
        "history": [],
        "createdAt": now,
        "updatedAt": now
    }
    
    with open(output, "x", encoding="utf-8") as handle:
        json.dump(state, handle, indent=2)
        handle.write("\n")
    PY
    
  2. Apply strict slug validation independently of JSON serialization.

  3. Reject control characters in the human-readable topic name if they are unnecessary.

  4. Validate the completed state against the documented schema before reporting successful pipeline creation.

  5. Write to a temporary file in the same directory, validate it, and atomically rename it into place.

  6. Add tests covering quotes, backslashes, Unicode, newlines, and other control characters.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/check_progress.sh:67
Finding

Progress Lookup Accepts Traversal Paths Outside the Learning Directory

Content
View full analysis

Vulnerability Details

File Location: scripts/check_progress.sh, lines 67-75
Vulnerability Type: Path traversal resulting in out-of-scope state-file inspection
Risk Level: Low

Vulnerable Code

bash
if [ $# -ge 1 ]; then
    # Show specific topic
    TOPIC_DIR="${LEARNING_DIR}/$1"
    if [ ! -d "$TOPIC_DIR" ]; then
        echo "Topic not found: $1"
        echo "Available topics:"
        ls -1 "$LEARNING_DIR" 2>/dev/null || echo "  (none)"
        exit 1
    fi
    echo "=== Learning Progress: $1 ==="
    show_topic "$TOPIC_DIR"

The selected directory is subsequently used to locate a state file:

bash
local state_file="${topic_dir}/state.json"

if [ ! -f "$state_file" ]; then
    echo "  [!] No state.json found"
    return
fi

Technical Analysis

The optional topic argument is appended directly to LEARNING_DIR and treated as a path. No slug validation, canonicalization, or containment check is performed.

A value containing ../ can therefore resolve to a directory outside memory/learning. If that directory contains a readable state.json, show_topic parses it and prints selected fields, including topic, status, day, session, curriculum progress, current subtopic, and score history.

Shell quoting prevents command injection but does not prevent filesystem traversal.

Attack Path

  1. An attacker invokes check_progress.sh with a traversal string instead of a valid topic slug.
  2. TOPIC_DIR resolves outside ${WORKSPACE}/memory/learning.
  3. The directory check succeeds if the resolved external directory exists.
  4. show_topic opens state.json in that directory.
  5. Selected JSON fields are printed to standard output.

A conceptual invocation is:

bash
bash scripts/check_progress.sh "../../../other-application"

Exploitation requires the resolved directory to contain a readable file named state.json.

Impact Ass

...[truncated 604 chars]

Remediation
View remediation

Remediation Suggestions

  1. Require the topic argument to match the same strict slug expression used by pipeline creation:

    bash
    TOPIC_SLUG="$1"
    if [[ ! "$TOPIC_SLUG" =~ ^[a-z0-9]+(-[a-z0-9]+)*$ ]]; then
        echo "Invalid topic slug." >&2
        exit 1
    fi
    
  2. Resolve the candidate directory canonically and verify that it remains a direct child of the canonical learning root.

  3. Reject path separators, . components, .. components, and control characters.

  4. Consider enumerating known topic directories and requiring an exact basename match rather than accepting an arbitrary path component.

  5. Add tests demonstrating rejection of traversal paths and symbolic links that resolve outside the learning root.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description presents the skill as an autonomous structured learning system that teaches users through cron-based 5-session feedback loops. The supplied code does not implement teaching, scheduling, session orchestration, or feedback-loop behavior. Instead, it is a read-only progress-reporting utility that inspects local state.json files under a learning workspace and prints status metrics. This is a materially different primary purpose from the declared functionality, so the description does not accurately represent what this code chunk actually does.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The instruction to directly modify ~/.openclaw/cron/jobs.json gives the skill write access to persistent user-level automation state without clear necessity for core learning functionality. A compromised or misbehaving skill could plant recurring jobs, alter execution timing, or persist further agent actions beyond the current session, creating durable and hard-to-notice system impact.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README advertises cron-based autonomous feedback loops that run without supervision, but it does not foreground the operational consequences such as recurring execution, persistent state changes, and ongoing file creation. In context, this is more dangerous because the skill is explicitly designed to continue acting after the initial interaction, which raises the risk of unexpected resource use or unauthorized persistence.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The activation language is broad enough to match common educational or exploratory requests, which can cause the skill to engage in situations where the user did not intend to authorize a persistent autonomous workflow. In this skill, that risk is amplified because activation leads to curriculum generation and recurring cron-based sessions rather than a one-shot response.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The text states that the agent schedules 5 sessions per day and that cron jobs handle the rest, but it does not present this as a clear user warning or explicit consent boundary. Because the skill creates recurring unattended activity, omission of a strong warning can mislead users into triggering a workflow with lasting system effects they did not expect.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The usage examples encourage invocation through ordinary phrases like "Learn Kubernetes" and "Teach me database design" without clearly distinguishing them from normal conversational help requests. That ambiguity increases the chance of accidental activation of a long-running autonomous process with ongoing file writes and scheduled execution.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The description says to use the skill when the user wants to deeply learn a subject and gives example triggers like "learn X", "teach me Y", and "master Z". These phrases are common everyday requests and, despite the later exclusions, the activation boundary remains broad enough to risk unintended invocation for normal informational queries.

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 · SKILL.md (reported line 47)May include surrounding context.

md
Use available search tools (web search, Tavily, SerpAPI — try what's available, fall back gracefully) to research the topic. Break into 15-20 subtopics ordered by prerequisites.

Write curriculum to `curriculum.md` with:
- Subtopic name
- Why it matters
- Prerequisites (which earlier subtopics are needed)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill instructs the agent to persistently modify ~/.openclaw/cron/jobs.json and create recurring autonomous behavior, but it does not prominently warn about system state changes, local data creation, and delayed future actions before reaching the confirmation stage. That can lead to users authorizing a learning action without understanding it creates durable scheduled jobs and stored topic data, which is risky in an agent environment with filesystem access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This methodology repeatedly instructs the agent to create cron jobs and one-shot scheduled tasks, but it provides no requirement for explicit user consent, visibility, scope limits, or safety checks around background execution. In an agent skill, scheduled persistence can cause unauthorized future actions, repeated external access, or file/system modification after the initiating interaction has ended, which materially increases operational risk.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

The playbook explicitly introduces session persistence by creating an S5 cron, allowing the agent's activity to continue after the current turn. Persistence is security-relevant because it enables delayed or repeated execution and can be abused to maintain ongoing autonomous behavior outside the user's immediate awareness.

Content

Scanner excerpt · references/playbook-template.md (reported line 149)May include surrounding context.

md
---

## S4 — Retry: Re-test & Create S5

**Goal:** Re-answer original questions with new understanding. Create S5 cron.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The playbook directs the agent to manage persistent cron jobs by reading and rewriting a user-level scheduler store, which goes beyond a narrow learning-session workflow. Even if intended for automation, modifying persistent scheduling state can create lasting side effects, unexpected executions, and a broader control surface than the user may realize from invoking a learning skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The playbook causes persistent scheduler changes without an explicit warning or consent checkpoint at the moment of change. Users may believe they are running a bounded learning session, while the skill silently installs follow-up execution, reducing transparency and increasing the risk of unauthorized persistence.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
80% confidence
Finding

The curriculum expansion step tells the agent to research advanced subtopics beyond the current curriculum when nearing the end. That capability is not necessary to execute the current learning loop for a given subtopic and introduces broader autonomous planning behavior than the manifest's immediate 'use when user wants to deeply learn a subject' framing implies.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Appending tomorrow's S1-S4 jobs extends the persistence issue by creating multiple future executions without explicit contemporaneous user approval. This compounds system impact over time and increases the chance of unwanted autonomous behavior continuing unnoticed.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The manifest centers on mastering complex topics through cron-based 5-session feedback loops, but the playbook also directs the agent to research new advanced subtopics, generate curriculum-preview.md, and plan future days' cron schedules. These are adjacent capabilities, yet they go beyond the core described loop execution into autonomous curriculum expansion and ongoing program management.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.