Back to skill

Security audit

skill-guard

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent security-scanning purpose, but its installer has unsafe deletion paths and mutable third-party execution that users should review before installing.

Install only if you are comfortable reviewing and hardening the shell script first. At minimum, validate skill slugs, add path containment checks before rm or mv, pin mcp-scan to a reviewed version, avoid curl-to-shell dependency installation, and treat --skip-scan, --force, and install-anyway as unsafe override paths.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:93
Finding
Unverified Remote Installer Executed Through a Shell Pipeline<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 93-96 **Vulnerability Type**: Remote payload retrieval and execution **Risk Level**: High ### Vulnerable Code ```markdown ## Requirements - `clawhub` CLI — `npm i -g clawhub` - `uv` — `curl -LsSf https://astral.sh/uv/install.sh | sh` ``` A matching command is also presented in the dependency error message at `scripts/safe-install.sh:86`: ```bash print_error "uvx not found. Install uv with: curl -LsSf https://astral.sh/uv/install.sh | sh" ``` The shell script only prints this command; it does not execute it automatically. However, both locations encourage users to execute it. ### Technical Analysis The installation instructions pipe the response from an external HTTPS endpoint directly into `sh`. The downloaded content is neither pinned to a reviewed version nor checked against a trusted checksum or digital signature before execution. Consequently, the effective code executed by the user can change after this Skill has been audited. HTTPS protects transport confidentiality and integrity under normal conditions, but it does not protect against compromise of the publisher account, hosting infrastructure, release process, or an incorrectly trusted certificate authority. Using this mechanism is not necessary for the Skill's core function. A versioned package or separately downloaded and verified installer could provide the same dependency without immediate execution of mutable remote content. ### Attack Path 1. The user follows the documented requirements or the error message emitted by `safe-install.sh`. 2. The user runs `curl -LsSf https://astral.sh/uv/install.sh | sh`. 3. The remote endpoint, publishing process, or associated infrastructure serves modified installer content. 4. `curl` transfers that content directly to the shell without local inspection or integrity verification. 5. The malicious content executes with all privileges and data access available to the invoking user. ...[truncated 557 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the pipeline with installation through a trusted package manager using an explicitly pinned version. 2. If a standalone installer is required, download it to a local file rather than piping it into a shell. 3. Publish and verify a cryptographic checksum or publisher signature before execution. 4. Display the verified script to the user or provide an opportunity for inspection before running it. 5. Pin the download to an immutable, version-specific artifact rather than a mutable generic installer URL. 6. Update the error message at `scripts/safe-install.sh:86` so that it does not recommend direct remote-to-shell execution. A safer conceptual process is: ```bash curl -fL -o uv-installer.sh "https://trusted.example/uv/<PINNED_VERSION>/install.sh" printf '%s %s\n' "<TRUSTED_SHA256>" "uv-installer.sh" | sha256sum -c - sh uv-installer.sh ``` The version and checksum must come from an independently authenticated source. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/safe-install.sh:29
Finding
Path Traversal in Skill Slug Reaches Recursive Deletion Operations<![CDATA[ ## Vulnerability Details **File Location**: `scripts/safe-install.sh`, lines 29-95 **Vulnerability Type**: Path traversal and unsafe recursive deletion **Risk Level**: High ### Vulnerable Code The script accepts an unrestricted positional argument as the skill slug: ```bash # Parse arguments while [[ $# -gt 0 ]]; do case $1 in --version) VERSION_ARG="--version $2" shift 2 ;; --force) FORCE_ARG="--force" shift ;; --skip-scan) SKIP_SCAN=true shift ;; --help|-h) echo "skill-guard: Secure skill installation with pre-install scanning" echo "" echo "Usage: safe-install.sh <skill-slug> [options]" echo "" echo "Options:" echo " --version <ver> Install specific version" echo " --force Overwrite existing installation" echo " --skip-scan Skip security scan (not recommended)" echo " --help Show this help" echo "" echo "Environment:" echo " CLAWHUB_WORKDIR Skills parent directory (default: ~/.openclaw/workspace)" exit 0 ;; -*) print_error "Unknown option: $1" exit 1 ;; *) SKILL_SLUG="$1" shift ;; esac done ``` It then interpolates the unvalidated value into a recursive deletion path: ```bash # Download skill to staging stage_skill() { print_info "Fetching $SKILL_SLUG to staging area..." rm -rf "$STAGING_DIR/skills/$SKILL_SLUG" mkdir -p "$STAGING_DIR" ``` Additional deletion sinks use the same value at `scripts/safe-install.sh:158` and `scripts/safe-install.sh:169`: ```bash if [[ -d "$SKILLS_DIR/$SKILL_SLUG" ]]; then if [[ -n "$FORCE_ARG" ]]; then rm -rf "$SKILLS_DIR/$SKILL_SLUG" else print_e ...[truncated 2580 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Validate the slug before using it in any path. Require it to be exactly one path component with a strict allowlist, for example: ```bash if [[ ! "$SKILL_SLUG" =~ ^[A-Za-z0-9][A-Za-z0-9._-]*$ ]] || [[ "$SKILL_SLUG" == "." || "$SKILL_SLUG" == ".." ]]; then print_error "Invalid skill slug" exit 1 fi ``` 2. Explicitly reject `/`, backslashes, control characters, empty values, `.` and `..`. 3. Canonicalize both the trusted root and the candidate path before deletion or movement. 4. Verify that the canonical candidate begins with the canonical root followed by a path separator. 5. Refuse to continue if canonicalization fails or if the candidate equals the root itself. 6. Apply the containment check independently to staging deletion, cleanup, forced replacement, scanning, and movement. 7. Avoid `rm -rf` where a narrower operation is sufficient. 8. Create a unique staging directory with `mktemp -d` for each run, reducing collisions and limiting deletion to a directory created by the current process. A containment check should follow this principle: ```bash root="$(realpath -m "$STAGING_DIR/skills")" candidate="$(realpath -m "$root/$SKILL_SLUG")" case "$candidate" in "$root"/*) ;; *) print_error "Resolved skill path escapes staging root" exit 1 ;; esac ``` Validation and containment must both be applied; relying on only one provides weaker defense in depth. ]]>

T08 · Insecure Dependencies

Error
Location
scripts/safe-install.sh:124
Finding
Unpinned Latest Scanner Package Is Downloaded and Executed<![CDATA[ ## Vulnerability Details **File Location**: `scripts/safe-install.sh`, line 124 **Vulnerability Type**: Mutable executable dependency **Risk Level**: High ### Vulnerable Code ```bash scan_output=$(uvx mcp-scan@latest --skills "$staged_path" 2>&1) || scan_exit_code=$? ``` ### Technical Analysis The script asks `uvx` to execute `mcp-scan@latest`. The `latest` selector is mutable and does not identify the exact scanner release that was reviewed with this Skill. A future package release can therefore change the code executed by the installer without any change to this repository. This creates a supply-chain execution channel through the package registry, package publisher account, and dependency resolution process. Running a third-party scanner is consistent with the declared security-scanning function. Executing an unpinned and potentially newly downloaded release on every invocation is not the minimum exposure necessary to provide that function. ### Attack Path 1. An attacker compromises the scanner's publisher account, release pipeline, registry entry, or another relevant supply-chain component. 2. The attacker publishes a malicious release that resolves through the `latest` selector. 3. A user invokes `safe-install.sh`. 4. `uvx` resolves and executes the malicious scanner release. 5. The malicious package runs with the invoking user's privileges while receiving the staged skill path. 6. It can access any other files, credentials, environment data, and network resources available to that user; it is not sandboxed by this script. ### Impact Assessment A compromised scanner release could execute arbitrary commands with the invoking user's privileges. It could read or alter user-accessible files, tamper with scan results, install a malicious skill despite reported success, steal credentials available to the process, or modify the user's agent workspace. No direct sensitive-data exfiltration logic was identified in the reviewed repository itself. ...[truncated 134 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace `mcp-scan@latest` with an exact, audited version. 2. Lock the complete dependency graph and verify package hashes where supported. 3. Treat scanner upgrades as explicit changes requiring review and testing. 4. Obtain packages only from an authenticated, approved registry. 5. Consider installing the scanner during a controlled setup phase rather than resolving executable code dynamically during every skill installation. 6. Run the scanner in a sandbox or container with: - Read-only access to the staged skill. - No access to unrelated home-directory content. - No inherited credentials unless strictly required. - Network access disabled unless scanning demonstrably requires it. - Resource and execution-time limits. 7. Verify scanner output using structured exit statuses or machine-readable results rather than only keyword matching. Conceptually, the invocation should use a reviewed release: ```bash scan_output=$(uvx "mcp-scan==<PINNED_VERSION>" --skills "$staged_path" 2>&1) || scan_exit_code=$? ``` The exact syntax and integrity controls should match the package manager's supported lock and verification mechanisms. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (27)

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Content
---
name: skill-guard
description: Scan ClawHub skills for security vulnerabilities BEFORE installing. Use when installing new skills from ClawHub to detect prompt injections, malware payloads, hardcoded secrets, and other threats. Wraps clawhub install with mcp-scan pre-flight checks.
---

# skill-guard

**The only pre-install security gate for ClawHub skills.**

## Why skill-guard?

| | **VirusTotal** (ClawHub built-in) | **skillscanner** (Gen Digital) | **skill-guard** |
|---|---|---|---|
| **When it runs** | After publish (server-side) | On-demand lookup | **Before install (client-side)** |
| **What it checks**
Confidence
80% confidence
Finding
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Instruction Override

High
Category
Prompt Injection
Content
| **AI-specific threats** | ❌ | ❌ | ✅ |
| **Install blocking** | ❌ | ❌ | ✅ |

**VirusTotal** catches known malware binaries — but won't flag `<!-- IGNORE PREVIOUS INSTRUCTIONS -->`.

**skillscanner** checks if Gen Digital has reviewed it — but can't scan new or updated skills.
Confidence
80% confidence
Finding
This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
| **AI-specific threats** | ❌ | ❌ | ✅ |
| **Install blocking** | ❌ | ❌ | ✅ |

**VirusTotal** catches known malware binaries — but won't flag `<!-- IGNORE PREVIOUS INSTRUCTIONS -->`.

**skillscanner** checks if Gen Digital has reviewed it — but can't scan new or updated skills.
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. 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
t-side)** |
| **What it checks** | Malware signatures | Their database | **Actual skill content** |
| **Prompt injections** | ❌ | ❌ | ✅ |
| **Data exfiltration URLs** | ❌ | ❌ | ✅ |
| **Hidden instructions** | ❌ | ❌ | ✅ |
| **AI-specific threats** | ❌ | ❌ | ✅ |
| **Install blocking** | ❌ | ❌ | ✅ |

**VirusTotal** catches known malware binaries — but won't flag `<!-- IGNORE PREVIOUS INSTRUCTIONS -->`.

**skillscanner** checks if Gen Digital has reviewed it — but can't scan new or updated skills.

**skill-guard** uses [mcp-scan](https://github.com/invariantlabs-ai/mcp-scan) (Invariant Labs, acquired by Snyk) to analyze what's actually in the skill, catches AI-specific threats, and blocks install if issues are found.

## The Problem

Skills can contain:
- 🎭 **Prompt injections** — hidden "ignore previous instructions" attacks
- 💀 **Malware payloads** — dangerous commands disguised in natural language  
- 🔑 **Hardcoded secrets** — API keys, t
Confidence
80% confidence
Finding
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Instruction Override

High
Category
Prompt Injection
Content
## The Problem

Skills can contain:
- 🎭 **Prompt injections** — hidden "ignore previous instructions" attacks
- 💀 **Malware payloads** — dangerous commands disguised in natural language  
- 🔑 **Hardcoded secrets** — API keys, tokens in plain text
- 📤 **Data exfiltration** — URLs that leak your conversations, memory, files
Confidence
80% confidence
Finding
This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.

Ae1

High
Category
analysis-evasion
Content
./scripts/safe-install.sh some-skill
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
./scripts/safe-install.sh some-skill
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
./scripts/safe-install.sh some-skill
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
./scripts/safe-install.sh some-skill
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Tool Parameter Abuse

High
Category
Tool Misuse
Content
Skill stays in `/tmp/skill-guard-staging/skills/<slug>/` (quarantined). You can:
1. **Review** — read the scan output, inspect the files
2. **Install anyway** — `mv /tmp/skill-guard-staging/skills/<slug> ~/.openclaw/workspace/skills/`
3. **Discard** — `rm -rf /tmp/skill-guard-staging/`

## Requirements
Confidence
90% confidence
Finding
Documenting 'rm -rf /tmp/skill-guard-staging/' as a routine action normalizes destructive shell usage and may be misapplied in an agent-assisted environment. In contexts where tools or users interpolate paths incorrectly, recursive forced deletion can cause broader filesystem damage than intended.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
Skill stays in `/tmp/skill-guard-staging/skills/<slug>/` (quarantined). You can:
1. **Review** — read the scan output, inspect the files
2. **Install anyway** — `mv /tmp/skill-guard-staging/skills/<slug> ~/.openclaw/workspace/skills/`
3. **Discard** — `rm -rf /tmp/skill-guard-staging/`

## Requirements
Confidence
85% confidence
Finding
Documenting 'rm -rf /tmp/skill-guard-staging/' as a routine action normalizes destructive shell usage and may be misapplied in an agent-assisted environment. In contexts where tools or users interpolate paths incorrectly, recursive forced deletion can cause broader filesystem damage than intended.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
Skill stays in `/tmp/skill-guard-staging/skills/<slug>/` (quarantined). You can:
1. **Review** — read the scan output, inspect the files
2. **Install anyway** — `mv /tmp/skill-guard-staging/skills/<slug> ~/.openclaw/workspace/skills/`
3. **Discard** — `rm -rf /tmp/skill-guard-staging/`

## Requirements
Confidence
90% confidence
Finding
Documenting 'rm -rf /tmp/skill-guard-staging/' as a routine action normalizes destructive shell usage and may be misapplied in an agent-assisted environment. In contexts where tools or users interpolate paths incorrectly, recursive forced deletion can cause broader filesystem damage than intended.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
stage_skill() {
    print_info "Fetching $SKILL_SLUG to staging area..."
    
    rm -rf "$STAGING_DIR/skills/$SKILL_SLUG"
    mkdir -p "$STAGING_DIR"
    
    # Install to staging directory (clawhub creates skills/<slug> under workdir)
Confidence
95% confidence
Finding
`rm -rf "$STAGING_DIR/skills/$SKILL_SLUG"` uses user-controlled `SKILL_SLUG` in a destructive filesystem operation without validating that it is a safe slug. If path traversal values such as `../../...` are accepted, an attacker could cause deletion outside the staging directory.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
if [[ -d "$SKILLS_DIR/$SKILL_SLUG" ]]; then
        if [[ -n "$FORCE_ARG" ]]; then
            rm -rf "$SKILLS_DIR/$SKILL_SLUG"
        else
            print_error "Skill already exists at $SKILLS_DIR/$SKILL_SLUG (use --force to overwrite)"
            exit 1
Confidence
97% confidence
Finding
On `--force`, the script deletes `"$SKILLS_DIR/$SKILL_SLUG"` using an unvalidated user-provided slug. If an attacker can supply path traversal input, this could remove arbitrary directories reachable from the configured skills base, making the impact destructive and potentially severe.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
# Cleanup staging
cleanup() {
    rm -rf "$STAGING_DIR/skills/$SKILL_SLUG" 2>/dev/null || true
}

# Main flow
Confidence
95% confidence
Finding
The cleanup function repeats the same unsafe pattern, recursively deleting a path constructed from untrusted `SKILL_SLUG`. Cleanup paths are often overlooked, but here they can be triggered in normal execution and may erase unintended filesystem locations if traversal is possible.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
echo "Options:"
        echo "  1. Review the issues above and decide if they're acceptable"
        echo "  2. Run: mv $STAGING_DIR/skills/$SKILL_SLUG $SKILLS_DIR/ to install anyway"
        echo "  3. Run: rm -rf $STAGING_DIR/skills/$SKILL_SLUG to discard"
        echo ""
        exit 2  # Exit code 2 = issues found, not installed
    fi
Confidence
95% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill documents shell-based install and file-moving workflows but does not declare any explicit tool scope or allowed-tools boundaries. In an agent ecosystem, missing permission metadata can lead to over-broad execution authority and makes it harder to enforce least privilege when the skill is invoked.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The documentation explicitly tells users they can bypass quarantine by manually moving a flagged skill into the live skills directory, and it mentions force overwrite without a strong warning. This weakens the protection model the skill claims to provide and creates a straightforward path for installing content already identified as risky.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The script advertises secure pre-install scanning but also supports `--skip-scan`, allowing installation without any analysis. That weakens the core security guarantee and can lead users or higher-level automation to trust an installation path that bypasses the advertised protection.

Session Persistence

Medium
Category
Rogue Agent
Content
echo ""
            echo "Options:"
            echo "  --version <ver>  Install specific version"
            echo "  --force          Overwrite existing installation"
            echo "  --skip-scan      Skip security scan (not recommended)"
            echo "  --help           Show this help"
            echo ""
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.

Rp1

Medium
Category
MCP Rug Pull
Confidence
65% confidence
Finding
uvx/uv tool run commands without ==version create a rug-pull risk.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding
The script executes `uvx mcp-scan@latest`, which pulls the latest scanner version at runtime rather than a pinned, reviewed version. That creates supply-chain risk: a compromised or breaking scanner release could change security decisions, produce false negatives, or execute unexpected code during the install flow.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The manifest describes the skill as scanning ClawHub skills before installation and wrapping install with pre-flight checks. This script not only scans but also moves the staged skill into the user's skills directory, making it an installer as well as a scanner.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
When the target skill directory already exists and --force is set, the script unconditionally runs rm -rf on the existing installation. Although the help text documents that --force overwrites, there is no interactive confirmation or immediate user-facing disclosure at the point of deletion before the destructive action occurs.

Vague Triggers

Low
Confidence
88% confidence
Finding
The description says to use the skill 'when installing new skills from ClawHub,' which is helpful but still broad and does not define explicit trigger phrases, exclusions, or negative examples. In a skill-selection system, this could overlap with many general install-related requests and cause unintended invocation.

Static analysis

Detected: suspicious.prompt_injection_instructions

Prompt-injection style instruction pattern detected.

Warn
Code
suspicious.prompt_injection_instructions
Location
SKILL.md:22