Back to skill

Security audit

Porting OpenClaw Skills Across Platforms

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a legitimate skill-porting helper, but its converter can copy files outside the selected skill folder through symlinks, so it needs review before use.

Install only if you are comfortable reviewing the converter before use. Run it only on trusted skill directories, inspect sources for symlinks first, use a scratch output folder, and do not publish or share generated ports until checking that no unintended local files were copied.

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/port_skill.py:332
Finding
Source Symlink Allows Files Outside the Skill Directory to Be Copied## Vulnerability Details **File Location**: `scripts/port_skill.py`, lines 332–378 **Vulnerability Type**: Source-directory boundary bypass through symbolic links **Risk Level**: Medium ### Vulnerable Code ```python for p in sorted(src.rglob("*")): if p.is_dir(): continue rel = p.relative_to(src) is_text = p.suffix.lower() in TEXT_EXTS if is_text: orig = p.read_text(encoding="utf-8", errors="replace") if _is_tool_catalog(str(rel), orig): warnings.append(f"Tool mapping document: {rel} skipped auto-replacement; must be fully rewritten as the target platform's tool table.") files_copied += 1 if not dry_run: dst = dst_root / rel dst.parent.mkdir(parents=True, exist_ok=True) dst.write_text(orig, encoding="utf-8") continue text = orig if rel.name == "SKILL.md": if fix_name and name_mismatch: text = _fix_name(text, skill_name) text = normalize_frontmatter(text, target) file_flags = [] text, n = transform_text(text, target, file_flags, str(rel)) files_copied += 1 if n: files_changed += 1 total_changes += n if strip_output_directives: text_after_strip, n_strip = _strip_output_directives(text) if n_strip: file_flags = [f for f in file_flags if not _is_output_directive_flag(f)] file_flags.append(f"{rel}: (auto-removed {n_strip} output directive(s))") directives_removed += n_strip text = text_after_strip flags.extend(file_flags) if text != orig: diffs.append((str(rel), orig, text)) if not dry_run: dst = dst_root / rel dst.parent.mkdir(parents=True, exist_ok=True) dst.write_text(text, encoding="utf-8") else: files_copied += 1 if not dry_run: ...[truncated 2472 chars]
Remediation
## Remediation Suggestions - Reject symbolic links before processing: ```python if p.is_symlink(): raise ValueError(f"symbolic links are not allowed in source skills: {p}") ``` - Resolve every candidate and enforce containment beneath the canonical source directory before reading or copying: ```python src_root = src.resolve() for p in sorted(src.rglob("*")): if p.is_symlink(): raise ValueError(f"symbolic links are not allowed: {p}") resolved = p.resolve(strict=True) if resolved != src_root and src_root not in resolved.parents: raise ValueError(f"source entry escapes source directory: {p}") if resolved.is_dir(): continue ``` - Prefer file-opening mechanisms with no-follow semantics, where supported, to reduce time-of-check/time-of-use symlink races. - Apply the same containment policy to every source entry regardless of whether it is treated as text or copied as binary data. - Fail closed when encountering broken links, special files, sockets, FIFOs, or device nodes; accept only regular files and directories. - Add regression tests covering text and binary symlinks to external files, nested symlinks, broken symlinks, and links changed during processing.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (14)

Ae1

High
Category
analysis-evasion
Content
aw skill's **structure is already compatible with the Agent Skills standard** (`SKILL.md` + frontmatter + `references/`/`scripts/`/`assets/`), and every platfor
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
aw skill's **structure is already compatible with the Agent Skills standard** (`SKILL.md` + frontmatter + `references/`/`scripts/`/`assets/`), and every platfor
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
Inventory the platform coupling points that may appear in OpenClaw skill content, organized into three categories: auto-replaceable / needs manual rewrite / not portable.

## A. Output Directives (delete or rewrite)

OpenClaw's assistant output directives are not recognized by other platforms and should be **deleted** (or rewritten to the target platform's equivalent mechanism):
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
## A. Output Directives (delete or rewrite)

OpenClaw's assistant output directives are not recognized by other platforms and should be **deleted** (or rewritten to the target platform's equivalent mechanism):

| Directive | Meaning | Handling |
|---|---|---|
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
## A. Output Directives (delete or rewrite)

OpenClaw's assistant output directives are not recognized by other platforms and should be **deleted** (or rewritten to the target platform's equivalent mechanism):

| Directive | Meaning | Handling |
|---|---|---|
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
## A. Output Directives (delete or rewrite)

OpenClaw's assistant output directives are not recognized by other platforms and should be **deleted** (or rewritten to the target platform's equivalent mechanism):

| Directive | Meaning | Handling |
|---|---|---|
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
## A. Output Directives (delete or rewrite)

OpenClaw's assistant output directives are not recognized by other platforms and should be **deleted** (or rewritten to the target platform's equivalent mechanism):

| Directive | Meaning | Handling |
|---|---|---|
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
## A. Output Directives (delete or rewrite)

OpenClaw's assistant output directives are not recognized by other platforms and should be **deleted** (or rewritten to the target platform's equivalent mechanism):

| Directive | Meaning | Handling |
|---|---|---|
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
if strip_output_directives:
                text_after_strip, n_strip = _strip_output_directives(text)
                if n_strip:
                    # Output directives already auto-removed are no longer flagged as "needs manual handling"
                    file_flags = [f for f in file_flags if not _is_output_directive_flag(f)]
                    file_flags.append(f"{rel}: (auto-removed {n_strip} output directive(s))")
                directives_removed += n_strip
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
if n_strip:
                    # Output directives already auto-removed are no longer flagged as "needs manual handling"
                    file_flags = [f for f in file_flags if not _is_output_directive_flag(f)]
                    file_flags.append(f"{rel}: (auto-removed {n_strip} output directive(s))")
                directives_removed += n_strip
                text = text_after_strip
            flags.extend(file_flags)
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
if n_strip:
                    # Output directives already auto-removed are no longer flagged as "needs manual handling"
                    file_flags = [f for f in file_flags if not _is_output_directive_flag(f)]
                    file_flags.append(f"{rel}: (auto-removed {n_strip} output directive(s))")
                directives_removed += n_strip
                text = text_after_strip
            flags.extend(file_flags)
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill instructs use of file-reading and file-writing behavior through `scripts/port_skill.py` and placement of converted files, but the skill frontmatter does not declare any tool scope such as `permissions` or `allowed-tools`. This creates an authorization ambiguity where an agent may perform filesystem actions without an explicit least-privilege declaration, increasing the chance of overbroad file access during porting.

Session Persistence

Medium
Category
Rogue Agent
Content
- **Pure knowledge/content** (no tool references, no `MEDIA:`/`cron`/`sessions_*`) → copy directly + normalize frontmatter.
- **References tools/platform-specific features** → run `port_skill.py` for mechanical replacement, then handle remaining items manually per the report.
- Run `--dry-run` first to preview, confirm, then actually write files.

## Workflow
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.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
`scripts/port_skill.py` performs deterministic conversion: tool names → system files/paths → frontmatter normalization → outputs a "needs manual handling" report.

Arguments: `--target claude-code|codex|cursor|hermes|opencode|generic|all`, `--dry-run` (preview), `--strip-output-directives` (automatically remove `MEDIA:`/`[embed`/`[[reply_*]]`/`[[audio_as_voice]]`), `--fix-name` (fix a name that doesn't match the directory name), `--validate`, `--json`.

Replacement precision: short English words (`read`/`write`/`exec`/`image`…) are replaced only inside backticks; non-English words (`sessions_*`/`memory_*`/`web_fetch`…) are replaced as bare words; `AGENTS.md` is rewritten to `CLAUDE.md` only for Claude Code. See [tool-mappings.md](references/tool-mappings.md) for the full mapping.
Confidence
80% 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

No suspicious patterns detected.