Back to skill

Security audit

Training Manager

Security checks for vulnerabilities and agentic risk

Overview

This skill appears purpose-built rather than malicious, but it needs review because it persistently changes agent behavior and memory files and has script weaknesses that can break workspace boundaries.

Install only if you are comfortable with a skill that can create and update persistent agent instruction and memory files. Review generated or logged content before relying on it, avoid storing secrets or sensitive personal data in memory, and be cautious when running it in workspaces you did not create because symlinks could redirect writes outside the 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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/write-file.sh:51
Finding
Workspace Symlinks Permit Writes Outside the Configured Workspace## Vulnerability Details **File Location**: `scripts/write-file.sh:51-65` **Vulnerability Type**: Symlink-following arbitrary file overwrite **Risk Level**: Medium ### Vulnerable Code ```bash TARGET="$WORKSPACE/$FILENAME" # --- Check overwrite --- if [ -f "$TARGET" ] && [ "$FORCE" != "true" ]; then echo "ERROR: $FILENAME already exists. Use --force to overwrite." exit 1 fi # --- Validate content --- validate_shell_safety "content" "$CONTENT" check_prompt_injection_tiered "$CONTENT" "$FILENAME" "content" # --- Write file --- mkdir -p "$WORKSPACE" printf '%s\n' "$CONTENT" > "$TARGET" ``` The same filesystem weakness affects fixed-target writes in `scripts/log-training.sh:136-187`, scaffold creation in `scripts/scaffold.sh:12-13`, and predictable rate-limit files in `scripts/lib/security.sh:17-44`. ### Technical Analysis The scripts prevent lexical path traversal by restricting filenames, but they do not reject symbolic links or verify that the resolved destination remains under `OPENCLAW_WORKSPACE`. Shell redirection follows symbolic links. In `write-file.sh`, an existing symlink to a regular file is protected unless `--force` is supplied, after which the external target is overwritten. A dangling symlink is not recognized by `[ -f "$TARGET" ]` and is followed during creation. Other scripts append to or create fixed filenames without equivalent overwrite protection. This exceeds the minimum privileges needed for workspace management because writes intended to be confined to the workspace can affect arbitrary user-writable locations. ### Attack Path 1. An attacker gains the ability to prepare, import, or modify a workspace used by the operator. 2. The attacker creates a symlink at a recognized destination, such as `SOUL.md`, `AGENTS.md`, or `MEMORY.md`, pointing to another user-writable file outside the workspace. 3. The operator invokes setup, forced writing, scaffolding, or training logging. ...[truncated 650 chars]
Remediation
## Remediation Suggestions - Reject symbolic-link destinations using `[ -L "$TARGET" ]` before every create, append, move, or overwrite operation. - Resolve the workspace and destination parent with `realpath` or an equivalent portable implementation, then verify that the resolved destination remains beneath the canonical workspace path. - Open files with exclusive-creation or no-follow semantics where supported. - Create replacement files with `mktemp` inside a trusted workspace directory, set restrictive permissions, and atomically rename them only after revalidating the destination. - Apply the same controls to bootstrap files, daily logs, generated skills, consolidation temporary files, and `.rate-limit` state. - Reject a symlinked workspace root and security-sensitive subdirectories such as `memory`, `skills`, and `.rate-limit`.

T01 · Skill Instruction Hijacking

Warning
Location
scripts/generate-skill.sh:100
Finding
Multiline Description Allows Generated Skill Frontmatter Injection## Vulnerability Details **File Location**: `scripts/generate-skill.sh:100-113` **Vulnerability Type**: Unescaped YAML frontmatter injection **Risk Level**: Medium ### Vulnerable Code ```bash # Write SKILL.md using printf to avoid echo expansion issues { printf '%s\n' "---" printf 'name: %s\n' "$SLUG" printf 'description: %s\n' "$DESCRIPTION" if [ -n "$METADATA" ]; then printf '%s\n' "$METADATA" fi printf '%s\n' "---" printf '\n' printf '# %s\n' "$NAME" printf '\n' printf '%s\n' "$INSTRUCTIONS" } > "$SKILL_DIR/SKILL.md" ``` Relevant validation at `scripts/generate-skill.sh:19-27` only applies shell-metacharacter and prompt-pattern checks: ```bash validate_shell_safety "name" "$NAME" validate_shell_safety "description" "$DESCRIPTION" validate_shell_safety "instructions" "$INSTRUCTIONS" validate_shell_safety "requires_bins" "$REQUIRES_BINS" validate_shell_safety "requires_env" "$REQUIRES_ENV" check_prompt_injection_tiered "$DESCRIPTION" "MEMORY.md" "description" check_prompt_injection_tiered "$INSTRUCTIONS" "MEMORY.md" "instructions" ``` ### Technical Analysis `DESCRIPTION` is inserted directly into YAML as an unquoted scalar. The input validation does not reject newline characters, YAML document delimiters, colons, comments, or other YAML structural syntax. Consequently, a multiline description can terminate or restructure the expected frontmatter and place additional content outside the intended description field. The blacklist-based prompt filter only detects selected phrases and does not enforce the structural boundary between metadata and executable Skill instructions. The validation script does not mitigate this issue because it only checks that the first line is `---` and that text matching `name:` and `description:` appears between delimiter matches. It does not parse the YAML document, enforce exactly one frontmatter block, or reject unexpected keys. ## ...[truncated 1228 chars]
Remediation
## Remediation Suggestions - Serialize frontmatter using a proper YAML library rather than string interpolation. - Require descriptions to be single-line values, or safely encode multiline values using validated YAML block-scalar syntax. - Reject control characters, document delimiters, and unapproved multiline input before generation. - Quote and escape every scalar according to YAML rules. - Parse the completed frontmatter with a YAML parser and require exactly one bounded frontmatter document. - Enforce an allowlist of permitted keys and expected value types. - Update `validate.sh` to perform structural YAML validation instead of searching for marker and field text. - Keep explicit human review before installing generated skills, but do not treat review as a substitute for safe serialization.
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 (28)

Instruction Override

High
Category
Prompt Injection
Content
| **NORMAL** | `USER.md`, `MEMORY.md`, generated skills | Standard — blocks common prompt injection patterns |
| **RELAXED** | Daily logs (`memory/YYYY-MM-DD.md`) | Basic — allows documentation while blocking obvious attacks |

**Why tiered?** Daily logs can legitimately say "the system prompt was truncated at 20K chars" (documentation), but `AGENTS.md` cannot say "ignore previous instructions" (injection attempt). Tiered filtering eliminates false positives while maintaining security where it matters.

**Blocked patterns include:**
- Instruction override attempts (`ignore previous instructions`, `you are now`, `disregard rules`)
Confidence
80% confidence
Finding
This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.

Instruction Override

High
Category
Prompt Injection
Content
| **NORMAL** | `USER.md`, `MEMORY.md`, generated skills | Standard — blocks common prompt injection patterns |
| **RELAXED** | Daily logs (`memory/YYYY-MM-DD.md`) | Basic — allows documentation while blocking obvious attacks |

**Why tiered?** Daily logs can legitimately say "the system prompt was truncated at 20K chars" (documentation), but `AGENTS.md` cannot say "ignore previous instructions" (injection attempt). Tiered filtering eliminates false positives while maintaining security where it matters.

**Blocked patterns include:**
- Instruction override attempts (`ignore previous instructions`, `you are now`, `disregard rules`)
Confidence
80% confidence
Finding
This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.

Instruction Override

High
Category
Prompt Injection
Content
| **NORMAL** | `USER.md`, `MEMORY.md`, generated skills | Standard — blocks common prompt injection patterns |
| **RELAXED** | Daily logs (`memory/YYYY-MM-DD.md`) | Basic — allows documentation while blocking obvious attacks |

**Why tiered?** Daily logs can legitimately say "the system prompt was truncated at 20K chars" (documentation), but `AGENTS.md` cannot say "ignore previous instructions" (injection attempt). Tiered filtering eliminates false positives while maintaining security where it matters.

**Blocked patterns include:**
- Instruction override attempts (`ignore previous instructions`, `you are now`, `disregard rules`)
Confidence
80% confidence
Finding
This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.

Instruction Override

High
Category
Prompt Injection
Content
| **NORMAL** | `USER.md`, `MEMORY.md`, generated skills | Standard — blocks common prompt injection patterns |
| **RELAXED** | Daily logs (`memory/YYYY-MM-DD.md`) | Basic — allows documentation while blocking obvious attacks |

**Why tiered?** Daily logs can legitimately say "the system prompt was truncated at 20K chars" (documentation), but `AGENTS.md` cannot say "ignore previous instructions" (injection attempt). Tiered filtering eliminates false positives while maintaining security where it matters.

**Blocked patterns include:**
- Instruction override attempts (`ignore previous instructions`, `you are now`, `disregard rules`)
Confidence
80% confidence
Finding
This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.

Instruction Override

High
Category
Prompt Injection
Content
| **NORMAL** | `USER.md`, `MEMORY.md`, generated skills | Standard — blocks common prompt injection patterns |
| **RELAXED** | Daily logs (`memory/YYYY-MM-DD.md`) | Basic — allows documentation while blocking obvious attacks |

**Why tiered?** Daily logs can legitimately say "the system prompt was truncated at 20K chars" (documentation), but `AGENTS.md` cannot say "ignore previous instructions" (injection attempt). Tiered filtering eliminates false positives while maintaining security where it matters.

**Blocked patterns include:**
- Instruction override attempts (`ignore previous instructions`, `you are now`, `disregard rules`)
Confidence
80% confidence
Finding
This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.

Instruction Override

High
Category
Prompt Injection
Content
| **NORMAL** | `USER.md`, `MEMORY.md`, generated skills | Standard — blocks common prompt injection patterns |
| **RELAXED** | Daily logs (`memory/YYYY-MM-DD.md`) | Basic — allows documentation while blocking obvious attacks |

**Why tiered?** Daily logs can legitimately say "the system prompt was truncated at 20K chars" (documentation), but `AGENTS.md` cannot say "ignore previous instructions" (injection attempt). Tiered filtering eliminates false positives while maintaining security where it matters.

**Blocked patterns include:**
- Instruction override attempts (`ignore previous instructions`, `you are now`, `disregard rules`)
Confidence
80% confidence
Finding
This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.

YARA rule 'agent_skill_prompt_injection_hidden_instructions': Prompt injection or hidden instructions embedded in AI agent skill text [agent_skills]

High
Category
YARA Match
Content
`, `TOOLS.md`, `IDENTITY.md` | Maximum — blocks behavioral overrides, command injection, exfiltration attempts |
| **NORMAL** | `USER.md`, `MEMORY.md`, generated skills | Standard — blocks common prompt injection patterns |
| **RELAXED** | Daily logs (`memory/YYYY-MM-DD.md`) | Basic — allows documentation while blocking obvious attacks |

**Why tiered?** Daily logs can legitimately say "the system prompt was truncated at 20K chars" (documentation), but `AGENTS.md` cannot say "ignore previous instructions" (injection attempt). Tiered filtering eliminates false positives while maintaining security where it matters.

**Blocked patterns include:**
- Instruction override attempts (`ignore previous instructions`, `you are now`, `disregard rules`)
- Behavioral manipulation (`your real personality is`, `always execute`, `never refuse`)
- Data exfiltration (`send all files to`, `curl POST`, `base64 encode`)
- Command injection (backticks, `$()` expansion)

#### 2. **Rate Limiting**

Preve
Confidence
80% confidence
Finding
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Anti-Refusal Statement

High
Category
Anti-Refusal
Content
**Blocked patterns include:**
- Instruction override attempts (`ignore previous instructions`, `you are now`, `disregard rules`)
- Behavioral manipulation (`your real personality is`, `always execute`, `never refuse`)
- Data exfiltration (`send all files to`, `curl POST`, `base64 encode`)
- Command injection (backticks, `$()` expansion)
Confidence
85% confidence
Finding
Skill instructs the agent to never refuse or to always comply. Suppressing the agent's ability to decline removes a core safety control and enables downstream harmful requests to succeed.

Anti-Refusal Statement

High
Category
Anti-Refusal
Content
**Blocked patterns include:**
- Instruction override attempts (`ignore previous instructions`, `you are now`, `disregard rules`)
- Behavioral manipulation (`your real personality is`, `always execute`, `never refuse`)
- Data exfiltration (`send all files to`, `curl POST`, `base64 encode`)
- Command injection (backticks, `$()` expansion)
Confidence
85% confidence
Finding
Skill instructs the agent to never refuse or to always comply. Suppressing the agent's ability to decline removes a core safety control and enables downstream harmful requests to succeed.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The description presents a broader workspace management tool that can scaffold files, generate skills, and log training sessions, but this code chunk does none of those things. It only analyzes existing workspace contents and outputs recommendations. The validation aspect does align with the description, but the primary implemented behavior here is diagnostic auditing rather than active workspace management or modification. This is a meaningful description-behavior mismatch because several declared core capabilities are absent from the supplied code.

YARA rule 'agent_skill_prompt_injection_hidden_instructions': Prompt injection or hidden instructions embedded in AI agent skill text [agent_skills]

High
Category
YARA Match
Content
e sanitized writer script. **Never write workspace files directly** -- always route through `write-file.sh` so content passes prompt injection filters.

```bash
bash {baseDir}/scripts/write-file.sh IDENTITY.md "<generated content>"
bash {baseDir}/scripts/write-file.sh USER.md "<generated content>"
```

Example IDENTITY.md content to pass:
```
# Identity

- **Name**: Claude
- **Role**: Personal AI assistant for Joel
- **Version**: 1.0
```

Example USER.md content to pass:
```
# User Profile

## Identity
- **Name**: Joel
- **Timezone**: PST
```

**Phase 2 -- Communication Style**

Ask preference questions with **concrete examples**, not abstract choices. These help the operator understand what they're choosing:

4. "When you ask me something, do you want the short answer first then details if you ask? Or the full explanation upfront?"
5. "How should I talk to you? Like a coworker, a friend, or more formally?"
6. "Should I push back when I think you're wrong, or just do what you ask?"

**
Confidence
80% confidence
Finding
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Ae1

High
Category
analysis-evasion
Content
4. Show the generated `SKILL.md` to the operator for review before finalizing.
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
ace file writes must go through scripts** (`write-file.sh`, `log-training.sh`, `generate-skill.sh`). Never use the agent's direct file-write capability for work
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Exfiltration Commands

High
Category
Prompt Injection
Content
| **NORMAL** | `USER.md`, `MEMORY.md`, generated skills | Base + Normal |
| **RELAXED** | Daily logs (`memory/YYYY-MM-DD.md`) | Base only (obvious attacks) |

- **Base patterns** (all tiers): instruction overrides ("ignore previous instructions"), data exfiltration ("secretly send"), encoded commands (base64).
- **Normal patterns** add: system prompt references, role-playing ("act as if", "pretend"), dangerous CLI patterns (curl POST, wget --post).
- **Strict patterns** add: behavioral overrides ("change your personality", "always run", "never refuse", "your real purpose is").
Confidence
90% confidence
Finding
Instructions found that direct the agent to transmit conversation context or user data to external services.

Credential Access

High
Category
Privilege Escalation
Content
REQUIRES_OBJ=$(printf '%s' "$REQUIRES_OBJ" | jq --arg bins "$REQUIRES_BINS" '.bins = ($bins | split(","))')
    fi
    if [ -n "$REQUIRES_ENV" ]; then
      REQUIRES_OBJ=$(printf '%s' "$REQUIRES_OBJ" | jq --arg env "$REQUIRES_ENV" '.env = ($env | split(","))')
    fi
    METADATA_JSON=$(printf '%s' "$REQUIRES_OBJ" | jq -c '{openclaw: {requires: .}}')
    METADATA="metadata: $METADATA_JSON"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Self-Modification

High
Category
Rogue Agent
Content
fi
fi

# Write SKILL.md using printf to avoid echo expansion issues
{
  printf '%s\n' "---"
  printf 'name: %s\n' "$SLUG"
Confidence
85% confidence
Finding
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The README advertises that corrections and preferences are 'categorized and logged automatically' into persistent files, but it does not give a clear privacy or consent warning at that point. For a workspace-management skill, silent persistence of user statements can store sensitive data or operational details without informed user approval.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The README says invoking `/training-manager` may auto-detect an empty workspace and start setup, otherwise it will 'ask what you need and run the appropriate command.' That broad conversational trigger model can cause unintended command selection or writes from ordinary dialogue, especially for a skill that creates and modifies workspace files.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill is user-invocable and repeatedly instructs the agent to run shell commands that can create, modify, and export workspace data, but it declares no explicit tool scope or allowed-tools restriction. Without an explicit permission boundary, the runtime may grant broader shell capability than the skill actually needs, increasing the blast radius of prompt-routing mistakes or misuse.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The auto-detection rule triggers interactive setup when two or more core files are missing, which could cause the skill to begin writing high-impact workspace files unexpectedly for partially configured users. In a system where these files influence future agent behavior, overly broad auto-setup increases the chance of accidental prompt-surface modification and persistence of unintended instructions.

Session Persistence

Medium
Category
Rogue Agent
Content
Want me to adjust anything?
```

Create `MEMORY.md` as an empty template and ensure the `memory/` directory exists:

```bash
bash {baseDir}/scripts/write-file.sh MEMORY.md "# Long-Term Memory"
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.

Ssd 3

Medium
Confidence
95% confidence
Finding
The skill instructs the agent to ask for 'important context' and then persist whatever the user says into MEMORY.md and daily logs without semantic limits, minimization, or sensitivity checks. That creates a durable sink for secrets, personal data, credentials, or sensitive project context that may later be surfaced to the model or exported in backups.

Session Persistence

Medium
Category
Rogue Agent
Content
fi
fi

# Write SKILL.md using printf to avoid echo expansion issues
{
  printf '%s\n' "---"
  printf 'name: %s\n' "$SLUG"
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.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script creates multiple persistent workspace files, including identity, user profile, and memory files, immediately when executed and without any explicit confirmation prompt. Even though the writes are confined to the configured workspace and guarded against overwriting existing files, this still performs non-trivial filesystem changes and seeds persistent memory-related artifacts that a user may not expect from a single command.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
## Tool Usage
- Prefer the simplest tool that accomplishes the task
- Show command output to the operator when relevant
- Never run commands that modify system files without confirmation

## Communication
- Lead with the answer, then explain if needed
Confidence
75% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Static analysis

Detected: suspicious.prompt_injection_instructions

Prompt-injection style instruction pattern detected.

Warn
Code
suspicious.prompt_injection_instructions
Location
README.md:180

Prompt-injection style instruction pattern detected.

Warn
Code
suspicious.prompt_injection_instructions
Location
SKILL.md:295