Back to skill

Security audit

done

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it claims, but its installer can overwrite or delete unintended folders when given a crafted skill ZIP.

Only install this skill if you trust both the installer and every ZIP passed to it. Review package `SKILL.md` names first, avoid untrusted archives, and prefer a fixed version that validates skill names, rejects path separators and traversal, uses unique temporary directories, and asks before overwriting or deleting anything.

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

T09 · Insecure Skill Coding Practices

Error
Location
install.py:101
Finding

Archive-Controlled Skill Name Enables Arbitrary Directory Deletion and File Placement

Content
View full analysis

Vulnerability Details

File Location: install.py:101-104, 123-153
Vulnerability Type: Unvalidated path construction and path traversal
Risk Level: High

Vulnerable Code

python
# Extract name
name_match = re.search(r'name:\s*(.+)', yaml_content)
if name_match:
    info['name'] = name_match.group(1).strip().strip('"\'')

def install_to_wsl(self, skill_dir, skill_name):
    """Install into WSL2"""
    target_dir = self.wsl_skills_dir / skill_name

    print(f"✓ Installing into WSL2: {target_dir}")

    # Delete the existing skill
    if target_dir.exists():
        shutil.rmtree(target_dir)

    # Copy
    shutil.copytree(skill_dir, target_dir)

    return target_dir

def install_to_windows(self, skill_dir, skill_name):
    """Back up to the Windows desktop"""
    target_dir = self.windows_skills_dir / skill_name

    print(f"✓ Backing up to Windows: {target_dir}")

    # Ensure that the directory exists
    self.windows_skills_dir.mkdir(parents=True, exist_ok=True)

    # Delete the existing skill
    if target_dir.exists():
        shutil.rmtree(target_dir)

    # Copy
    shutil.copytree(skill_dir, target_dir)

    return target_dir

Technical Analysis

The destination directory name is read directly from the untrusted name field in the archive's SKILL.md. The value is stripped of quotes but is not validated as a single safe filename component.

Python's pathlib does not guarantee that joining an untrusted path to a trusted base keeps the resulting path beneath that base. A name containing parent-directory components, such as ../../target, can escape the configured skills directory. If skill_name is an absolute path, the absolute path supersedes the intended base path entirely.

The escaped path is passed to shutil.rmtree() before shutil.copytree() is called. Consequently, an attacker-controlled package can cause the installer to recursively delete an existing directory and then place package-controlled files at the ...[truncated 2142 chars]

Remediation
View remediation

Remediation Suggestions

  1. Treat the skill name as a single filename component rather than a path.
  2. Enforce a strict allowlist, for example:
    python
    SAFE_SKILL_NAME = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$")
    
    if not SAFE_SKILL_NAME.fullmatch(skill_name):
        raise ValueError("Invalid skill name")
    
  3. Explicitly reject:
    • Absolute paths.
    • / and \ path separators.
    • . and .. components.
    • Empty names.
    • Platform-specific drive or UNC path syntax.
  4. Resolve both the trusted base and proposed destination, then verify containment before deletion or copying:
    python
    base = self.wsl_skills_dir.resolve()
    target = (base / skill_name).resolve()
    
    if target.parent != base:
        raise ValueError("Skill destination escapes the installation directory")
    
  5. Apply equivalent validation independently to the WSL and Windows destinations.
  6. Avoid recursively deleting a destination until all archive metadata and paths have passed validation.
  7. Consider installing into a newly created staging directory and using an atomic rename only after validation succeeds.
  8. Refuse unsafe input rather than attempting to remove traversal components automatically, because normalization can conceal malicious intent.

T09 · Insecure Skill Coding Practices

Warning
Location
install.py:22
Finding

Predictable Shared Temporary Directory Permits Race Conditions and Installation Interference

Content
View full analysis

Vulnerability Details

File Location: install.py:22, 59-66, 155-159
Vulnerability Type: Unsafe predictable temporary directory and check-then-act race condition
Risk Level: Medium

Vulnerable Code

python
class SkillInstaller:
    def __init__(self):
        self.wsl_skills_dir = Path.home() / ".openclaw" / "workspace" / "skills"
        self.windows_skills_dir = Path("/mnt/c/Users/yanha/Desktop/skills")
        self.temp_dir = Path("/tmp/done-skill-install")

def extract_zip(self, zip_path):
    """Extract ZIP file"""
    print(f"✓ Extracting: {zip_path}")

    # Clean the temporary directory
    if self.temp_dir.exists():
        shutil.rmtree(self.temp_dir)
    self.temp_dir.mkdir(parents=True)

    # Extract
    with zipfile.ZipFile(zip_path, 'r') as zip_ref:
        zip_ref.extractall(self.temp_dir)

def cleanup(self):
    """Clean temporary files"""
    if self.temp_dir.exists():
        shutil.rmtree(self.temp_dir)
        print(f"✓ Temporary files cleaned")

Technical Analysis

Every invocation uses the same predictable path, /tmp/done-skill-install. The implementation separately checks whether the path exists, removes it, creates it, extracts files into it, and later removes it. These check-then-act sequences are not atomic.

A shared temporary path creates interference between concurrent installer processes. One process can remove or replace the directory while another process is extracting, reading metadata, copying package content, or cleaning up. A local actor capable of modifying the directory—such as the same user, another process operating under the same account, or another user where local permissions are configured too broadly—may also attempt to substitute extracted files before they are copied into trusted skill locations.

The exploitability across separate local accounts depends on directory ownership, the process umask, /tmp protections, and platform-specific symbolic-link and recursive-removal safeguard ...[truncated 1769 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace the fixed path with a unique, securely created temporary directory:
    python
    import tempfile
    
    with tempfile.TemporaryDirectory(prefix="done-skill-install-") as temp:
        temp_dir = Path(temp)
        with zipfile.ZipFile(zip_path, "r") as zip_ref:
            zip_ref.extractall(temp_dir)
        # Validate and install while still inside this context.
    
  2. Keep extraction, validation, and copying inside the TemporaryDirectory context so cleanup occurs automatically.
  3. Do not perform separate existence checks before creating or deleting temporary resources.
  4. Ensure temporary directories are created with permissions that prevent access by unrelated local users.
  5. Use a distinct staging directory for every invocation so concurrent installations cannot delete or alter each other's files.
  6. Validate archive entries and package metadata before copying anything into a trusted destination.
  7. Where practical, verify that extracted files remain regular files or directories beneath the staging root before installation and reject unexpected symbolic links or special files.
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (11)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The documented behavior understates the real risk: the skill performs writes, backup copies, cleanup deletion, fixed-path access, and automatic overwrite of existing skill directories. Because it installs content from an archive into trusted skill locations, a user may trigger destructive replacement or persistence of untrusted files without understanding the full consequences.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 65)May include surrounding context.

md
自动从 `SKILL.md` 提取:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README explicitly promises automatic extraction, installation into WSL2, backup to the Windows desktop, and cleanup of temporary files, but it does not warn users that invoking the skill will modify files across multiple environments. This can cause unintended file-system changes, overwrite existing content, or remove artifacts the user expected to inspect, especially when the input archive is untrusted.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill describes file extraction, copying, cleanup, and overwrite behavior but declares no explicit tool scope or permission boundaries. In practice this enables filesystem read/write actions without a clear least-privilege contract, increasing the chance of unintended or unsafe file operations when the skill is invoked.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The description does not clearly disclose that the skill will automatically overwrite existing directories and copy files into persistent locations on both WSL and the Windows desktop. Missing this warning weakens informed consent and can lead users to authorize destructive or privacy-impacting filesystem changes unintentionally.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger phrases are very broad and overlap with normal conversational text such as 'done' or '帮我 done', making accidental activation plausible. Because activation leads to archive extraction and file-copy/install behavior, an attacker could socially engineer a user into invoking the skill with ordinary-looking language.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The installer deletes any existing target skill directory with shutil.rmtree() before reinstalling, without confirming with the user or validating that the destination is safe to remove. If the parsed skill name is unexpected, maliciously crafted, or collides with an existing directory, this can cause irreversible loss of user data in the WSL skills path.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The Windows backup directory is also recursively deleted and recreated without prompting, creating the same overwrite/data-loss risk on the user's desktop. Because the destination name is derived from untrusted SKILL.md metadata, a crafted archive could cause overwriting of an unintended directory under the configured Windows skills location.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README presents the skill name, instructions, and required invocation phrase only in Chinese, which implies a fixed language requirement without any user opt-in or alternative locale guidance. This can violate language/locale policy when a skill constrains interaction to a specific language without documenting that choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The skill documentation, usage examples, and trigger phrases are presented only in Chinese, implying a language-specific interaction model without offering a user choice. This can violate language/locale policy where skills should not force a specific language unless documented as region-specific or opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file's natural-language description, usage messages, and status output are written only in Chinese, which imposes a specific language on users. There is no opt-in, language selection, or documented justification that the tool is intended only for a Chinese-speaking or region-specific context.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.