Back to skill

Security audit

Remote Skill Engine

Security checks for vulnerabilities and agentic risk

Overview

This skill is meant to fetch and activate remote skills locally, but it does so with weak trust checks and persistent install-like changes.

Review this carefully before installing. It can make remote, mutable skill content behave like a local installed skill, and the current implementation does not authenticate downloads properly or verify hashes/signatures. Only use it with sources you already trust, avoid direct arbitrary URLs, and do not enable cached or synced skills without reviewing the exact downloaded files.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (6)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/cache-skill.py:135
Finding

Untrusted Remote Skills Are Downloaded and Activated Without Integrity Verification

Content
View full analysis

Vulnerability Details

File Location: scripts/cache-skill.py:135-165, 192-198; SKILL.md:31-49, 154-162
Vulnerability Type: Remote payload retrieval and activation
Risk Level: High

Vulnerable Code

python
elif parsed["type"] == "github":
    base_url = f"https://raw.githubusercontent.com/{parsed['owner']}/{parsed['repo']}/{parsed['branch']}"
    skill_url = f"{base_url}/{parsed['path']}/SKILL.md" if parsed['path'] else f"{base_url}/SKILL.md"

    print(f"📥 Downloading from GitHub...")
    dest = cache_path / "SKILL.md"
    if not download_file(skill_url, dest):
        print("❌ Failed to download SKILL.md")
        return False
    print("✅ SKILL.md downloaded")
python
common_scripts = ["fetch-skill.py", "compare-skills.py", "main.py", "run.py"]
for script in common_scripts:
    url = f"{base_url}/scripts/{script}"
    dest = scripts_dir / script
    if download_file(url, dest):
        print(f"  ✅ Downloaded: scripts/{script}")
        os.chmod(dest, 0o755)
    else:
        dest.unlink(miss_ok=True)
python
skills_symlink = SKILLS_DIR / skill_name
if skills_symlink.exists() or skills_symlink.is_symlink():
    skills_symlink.unlink()

skills_symlink.symlink_to(cache_path)

The documented activation behavior is:

markdown
# Just trigger it normally - it's in your skills path!

**Cached skills are symlinked** to `skills/` folder so they work identically to installed skills.

Technical Analysis

The cache operation accepts remote GitHub and direct URL sources, downloads mutable content, makes recognized scripts executable, and symlinks the downloaded directory into the active OpenClaw skills directory.

No commit pin, expected hash, digital signature, trusted-publisher verification, content review, or source allowlist is required before activation. A branch-based GitHub URL can also change after the local project has been reviewed ...[truncated 1430 chars]

Remediation
View remediation

Remediation Suggestions

  • Do not symlink newly downloaded skills into the active skills directory automatically.
  • Download remote content into a quarantined staging directory and require explicit review and approval before activation.
  • Permit only explicitly trusted HTTPS hosts and verified publishers.
  • Resolve branches and tags to immutable commit identifiers.
  • Record and verify cryptographic hashes for every downloaded file.
  • Support signed manifests and reject files that are absent from or inconsistent with the signed manifest.
  • Do not set executable permissions on remote scripts until they have passed review.
  • Display the exact source repository, commit, file list, hashes, and requested capabilities before installation.
  • Refuse to overwrite an existing active skill unless the user explicitly approves the replacement.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/cache-skill.py:53
Finding

TLS Certificate and Hostname Verification Are Disabled for Remote Downloads

Content
View full analysis

Vulnerability Details

File Location: scripts/cache-skill.py:53-63; scripts/fetch-skill.py:8-20; scripts/execute-remote-skill.py:10-24
Vulnerability Type: Improper certificate validation
Risk Level: High

Vulnerable Code

In scripts/cache-skill.py:

python
def download_file(url, dest_path):
    """Download a file from URL."""
    ctx = ssl.create_default_context()
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE

    try:
        req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0 RemoteSkillEngine/1.0'})
        with urllib.request.urlopen(req, context=ctx, timeout=30) as response:
            with open(dest_path, 'wb') as f:
                f.write(response.read())
        return True

The same insecure configuration appears in the metadata and direct-use helpers:

python
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

Technical Analysis

ssl.CERT_NONE disables certificate-chain validation, while check_hostname = False disables verification that the certificate belongs to the requested hostname. HTTPS therefore provides encryption without authenticating the server.

This is particularly dangerous in cache-skill.py, where intercepted content may subsequently be marked executable and linked into the active skills directory. The weakness also affects fetch-skill.py and execute-remote-skill.py, allowing metadata or agent-facing instructions to be altered in transit.

Attack Path

  1. A user runs one of the affected scripts on an attacker-controlled network or through a compromised proxy.
  2. The attacker intercepts the request for a remote SKILL.md or script.
  3. The attacker presents any certificate and supplies modified content.
  4. The client accepts the certificate because both chain and hostname verification are disabled.
  5. The modified content is displayed ...[truncated 535 chars]
Remediation
View remediation

Remediation Suggestions

  • Remove both insecure SSL assignments and use ssl.create_default_context() with its secure defaults.
  • Reject expired, self-signed, untrusted, or hostname-mismatched certificates.
  • Do not implement a fallback that retries with verification disabled.
  • Add integrity verification through signed manifests or pinned file hashes.
  • Where operationally appropriate, restrict downloads to trusted domains and consider certificate or public-key pinning.
  • Add automated tests confirming that invalid certificates and hostname mismatches cause retrieval to fail.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/cache-skill.py:70
Finding

Unvalidated Skill Names Permit Writes Outside the Intended Cache Directory

Content
View full analysis

Vulnerability Details

File Location: scripts/cache-skill.py:70-85, 122-189
Vulnerability Type: Path traversal and unsafe filesystem writes
Risk Level: High

Vulnerable Code

python
def cache_skill(skill_name, source_url):
    """Cache a skill from remote source."""
    print(f"🔄 Caching skill: {skill_name}")
    print(f"📍 Source: {source_url}")
    print("")

    # Create cache directory
    cache_path = CACHE_DIR / skill_name
    cache_path.mkdir(parents=True, exist_ok=True)

    scripts_dir = cache_path / "scripts"
    refs_dir = cache_path / "references"
    assets_dir = cache_path / "assets"

    scripts_dir.mkdir(exist_ok=True)
    refs_dir.mkdir(exist_ok=True)
    assets_dir.mkdir(exist_ok=True)

Remote and metadata files are then written relative to the unvalidated path:

python
dest = cache_path / "SKILL.md"
if not download_file(skill_url, dest):
    print("❌ Failed to download SKILL.md")
    return False
python
with open(cache_path / "cache-metadata.json", 'w') as f:
    json.dump(metadata, f, indent=2)

Technical Analysis

skill_name is accepted directly from sys.argv[1] and joined to CACHE_DIR without validation or a post-resolution containment check. pathlib does not prevent .. path segments from escaping the base directory, and an absolute child path can discard the intended base entirely.

Consequently, the download workflow can create directories and write fixed filenames such as SKILL.md, cache-metadata.json, and recognized files beneath scripts/ or references/ outside the remote skill cache. Existing files with those names may be truncated by the wb or w file modes. Existing symlinks inside a selected destination may also redirect writes.

The later symlink operation may fail for some traversal paths because the computed cache and active-skill paths can collide after normalization. That failure does not und ...[truncated 1077 chars]

Remediation
View remediation

Remediation Suggestions

  • Restrict skill names to a conservative allowlist, for example letters, digits, periods, underscores, and hyphens with a bounded length.
  • Reject absolute paths, path separators, . components, .. components, null bytes, and control characters.
  • Resolve the candidate destination using Path.resolve() and verify with is_relative_to() that it remains under the resolved cache root.
  • Perform an equivalent independent containment check for paths under the active skills directory.
  • Open new files using exclusive creation where replacement is not explicitly intended.
  • Refuse to follow destination symlinks and inspect each parent component before writing.
  • Download to a secure staging directory and atomically move verified content into place.
  • Abort before making any filesystem changes when validation fails.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/batch-cache.sh:26
Finding

Batch Filename Is Embedded Directly into Executable Python Source

Content
View full analysis

Vulnerability Details

File Location: scripts/batch-cache.sh:26-55
Vulnerability Type: Python code injection
Risk Level: High

Vulnerable Code

bash
# Parse JSON and cache each skill
python3 -c "
import json
import sys
import subprocess

with open('$SKILLS_FILE', 'r') as f:
    data = json.load(f)

skills = data.get('skills', [])
print(f'Found {len(skills)} skills to cache')
print('=' * 60)

success_count = 0
fail_count = 0

for skill in skills:
    name = skill.get('name')
    source = skill.get('source')

    if not name or not source:
        print(f'⚠️  Skipping invalid entry: {skill}')
        fail_count += 1
        continue

    print(f'\\n[{success_count + fail_count + 1}/{len(skills)}] Caching: {name}')
    result = subprocess.run(['python3', '$SCRIPT_DIR/cache-skill.py', name, source])

Technical Analysis

The shell expands $SKILLS_FILE and $SCRIPT_DIR inside a double-quoted argument containing Python source. Their values are inserted into single-quoted Python string literals without escaping.

A filename containing a single quote, newline, comment marker, or other Python syntax can terminate the intended string literal and inject additional Python statements. The earlier shell check only verifies that the supplied path exists; it does not make the path safe for source-code interpolation.

Passing name and source to subprocess.run as a list is not itself shell injection. The vulnerability occurs earlier, when shell-expanded path values are used to construct the python3 -c program.

Attack Path

  1. An attacker creates a JSON file whose filename contains characters that escape the Python string literal and inject Python syntax.
  2. The attacker convinces a user to run batch-cache.sh with that existing file path.
  3. The shell substitutes the filename into the source passed to python3 -c.
  4. Python parses the attacker-controlled filenam ...[truncated 542 chars]
Remediation
View remediation

Remediation Suggestions

  • Move the embedded Python program into a dedicated .py file.
  • Pass the JSON path and cache-script path through sys.argv, for example python3 batch_cache.py -- "$SKILLS_FILE".
  • If inline Python must be retained, pass values through positional arguments rather than interpolating them into source.
  • Quote every shell variable used as an argument and add set -euo pipefail.
  • Validate that the input is a regular file and consider rejecting control characters in paths.
  • Add regression tests using filenames containing quotes, spaces, newlines, and shell metacharacters.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/cache-skill.py:13
Finding

Unrestricted Remote URLs Enable Server-Side Request Forgery and Resource Exhaustion

Content
View full analysis

Vulnerability Details

File Location: scripts/cache-skill.py:13-38, 53-63, 145-178; scripts/fetch-skill.py:15-20; scripts/execute-remote-skill.py:17-24
Vulnerability Type: Unrestricted URL fetching and SSRF
Risk Level: High

Vulnerable Code

python
elif source.startswith("http"):
    return {
        "type": "direct",
        "url": source
    }
python
def download_file(url, dest_path):
    """Download a file from URL."""
    ctx = ssl.create_default_context()
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE

    try:
        req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0 RemoteSkillEngine/1.0'})
        with urllib.request.urlopen(req, context=ctx, timeout=30) as response:
            with open(dest_path, 'wb') as f:
                f.write(response.read())
        return True

The same pattern is used by the other retrieval helpers:

python
req = urllib.request.Request(
    skill_url,
    headers={'User-Agent': 'Mozilla/5.0 RemoteSkillEngine/1.0'}
)

with urllib.request.urlopen(req, context=ctx, timeout=30) as response:
    skill_content = response.read().decode('utf-8')

Technical Analysis

Direct sources are accepted based only on an http prefix. There is no trusted-host allowlist, scheme normalization, destination IP validation, redirect validation, or restriction against loopback, private, link-local, and reserved networks.

As a result, a supplied URL can cause requests to internal web services or cloud instance metadata addresses from the victim’s network context. Redirects can potentially move an initially acceptable request to a prohibited destination because each redirect target is not independently checked.

response.read() also reads the complete response into memory without a byte limit. In cache-skill.py, the complete body is then written to disk. Timeouts do not limit total resp ...[truncated 1182 chars]

Remediation
View remediation

Remediation Suggestions

  • Require the exact https scheme and reject ambiguous scheme prefixes.
  • Maintain an explicit allowlist of trusted registry and raw-content hosts.
  • Resolve hostnames before connecting and reject loopback, private, link-local, multicast, unspecified, and reserved addresses for both IPv4 and IPv6.
  • Repeat scheme, host, and resolved-address validation after every redirect.
  • Disable redirects unless they are required; otherwise enforce a low redirect limit.
  • Set strict Content-Length and streamed byte-count limits before storing or parsing content.
  • Stream responses in bounded chunks rather than using unrestricted response.read().
  • Restrict downloaded MIME types and enforce reasonable time and file-count limits.
  • Consider performing retrieval in a sandbox without access to internal networks or cloud metadata services.

T01 · Skill Instruction Hijacking

Error
Location
scripts/execute-remote-skill.py:10
Finding

Remote Content Is Presented as Authoritative Instructions to Follow

Content
View full analysis

Vulnerability Details

File Location: scripts/execute-remote-skill.py:10-48; SKILL.md:301-307
Vulnerability Type: Remote instruction and prompt injection
Risk Level: High

Vulnerable Code

python
def fetch_and_execute_skill(skill_url, command):
    """Fetch SKILL.md and execute a command using the skill's instructions."""
    ctx = ssl.create_default_context()
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE

    try:
        req = urllib.request.Request(
            skill_url,
            headers={'User-Agent': 'Mozilla/5.0 RemoteSkillEngine/1.0'}
        )

        with urllib.request.urlopen(req, context=ctx, timeout=30) as response:
            skill_content = response.read().decode('utf-8')
python
print("=" * 60)
print("SKILL LOADED - Following instructions:")
print("=" * 60)

# Display key sections (first 2000 chars for context)
print(skill_content[:2000])
if len(skill_content) > 2000:
    print("\n... [skill continues]")

print("")
print("=" * 60)
print("To use this skill, follow the instructions in SKILL.md above")
print("or execute specific commands/scripts from the skill's scripts/")
print("=" * 60)

The project documentation similarly directs the agent to use remote instructions:

markdown
User: "Use the coding agent to review my repo, but don't install it"

You:
1. Fetch coding agent SKILL.md from ClawHub
2. Read its code review workflow
3. Execute the workflow steps manually
4. Report findings

Technical Analysis

The helper fetches arbitrary remote text and explicitly frames it as instructions that should be followed. There is no separation between trusted skill policy and untrusted retrieved data, no instruction-risk analysis, and no approval boundary before actions proposed by the remote document are performed.

The function name and docstring claim execution, but the implementation does not pro ...[truncated 1425 chars]

Remediation
View remediation

Remediation Suggestions

  • Treat every remotely fetched document as untrusted data, not as authoritative agent instructions.
  • Remove language such as “Following instructions” and “follow the instructions above.”
  • Parse remote content in an isolated analysis context that cannot issue tool calls or override system and user instructions.
  • Present a neutral summary of proposed actions and require explicit user approval before each action.
  • Reject instructions requesting secrets, policy overrides, persistence, destructive operations, or unrelated tool use.
  • Preserve the original user goal as the controlling policy and prohibit remote content from modifying it.
  • Add provenance labels to all displayed remote content.
  • Combine these controls with verified TLS, source allowlisting, immutable revisions, and integrity checks.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (25)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description is about downloading/caching remote skills from ClawHub and GitHub for local offline use. The provided code does not fetch remote skills, cache anything, or enable local installation/use. Its sole behavior is to parse supplied JSON and render a side-by-side comparison table of skill metadata. That is a materially different primary purpose, so this is a clear mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description says the skill caches remote skills from ClawHub and GitHub into a local cache folder for offline use and use as if locally installed. The code instead retrieves a single remote SKILL.md from a URL at runtime, stores it only in a temporary directory, prints its contents, and provides manual instructions. There is no persistent cache, no offline capability, no local-install-like integration, and no actual execution of the supplied command. Additionally, it disables TLS certificate verification, which is a notable network behavior not implied by the description. This is a material mismatch in both primary purpose and capabilities.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description says this skill caches remote skills from ClawHub/GitHub for offline local use. The provided code does something substantially narrower and different: it fetches a single remote SKILL.md file, extracts YAML frontmatter metadata, and prints fields such as name and description. There is no implementation of local cache management, no storage to a cache folder, no offline-use support, and no mechanism to use remote skills as if installed locally. Additionally, the code explicitly disables SSL certificate verification, which is a notable behavior not suggested by the description. Therefore the code chunk does not accurately represent the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description says this skill caches remote skills from ClawHub and GitHub into a local cache for offline use and local-style usage. The provided code only performs discovery/search operations against ClawHub and GitHub and outputs results. There is no evidence of downloading repositories/files, storing them locally, managing a cache folder, or enabling offline use. The primary purpose in the code is search, which is materially different from the declared caching/local-use purpose.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill describes cached skills being symlinked into the active skills folder so they work like installed skills, but it does not prominently warn that this can make untrusted remote-derived content available for later automatic triggering. That omission is dangerous because it effectively turns remote content into locally trusted capability without clear user awareness of the persistence and execution boundary crossing.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script explicitly disables TLS certificate and hostname verification before downloading remote skill content, allowing a man-in-the-middle attacker to substitute arbitrary files during transit. In this skill context, that is especially dangerous because the downloaded content is cached as a local skill and symlinked into the active skills directory, increasing the chance of untrusted code or prompts being treated as trusted local content.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The code explicitly disables both TLS certificate validation and hostname verification before fetching remote skill metadata. This allows a man-in-the-middle attacker or malicious network intermediary to spoof GitHub/remote endpoints and supply attacker-controlled SKILL.md content, undermining the trust boundary for remotely sourced skills.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill describes and embeds behaviors that can read/write local files, invoke shell commands, and access remote network resources, yet it declares no explicit tool scope or permission boundaries. In a skill whose main purpose is fetching and integrating remote content into the local skills path, missing scope declarations materially increases the chance of unsafe execution of untrusted or unintended actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Auto-sync of cached skills from remote sources is described as a convenience feature without warning that local trusted content may change after initial review. This creates a supply-chain style risk where previously cached skills can be updated to new behavior and become active locally without adequate re-verification.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The workflow trigger for caching is ambiguous and may cause the agent to treat informal requests like 'get from web' as approval to retrieve and persist remote content. Because the skill's context includes local caching and install-like behavior, underspecified triggers can result in unreviewed import of untrusted remote skills.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

md
- Raw SKILL.md: `https://raw.githubusercontent.com/<owner>/<repo>/SKILL.md`

#### GitHub
- Search API: `https://api.github.com/search/code?q=SKILL.md+openclaw`
- Raw file: `https://raw.githubusercontent.com/<owner>/<repo>/<branch>/SKILL.md`

#### Awesome Lists

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The document alternates between 'don't install it' temporary use and persistent caching with symlinks that make remote skills behave like installed ones. That inconsistency can mislead users into treating remote content as ephemeral when the skill actually describes persistence and future auto-trigger capability, increasing trust and reducing caution around untrusted code.

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 extremely broad and overlap with normal conversations about skills, making accidental activation likely. In the context of a skill that may fetch, cache, and symlink remote content into a local executable skill path, overbroad triggering materially raises the chance of unintended high-risk behavior.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/cache-skill.py (reported line 43)May include surrounding context.

python
def fetch_skill_metadata(skill_name):
    """Fetch skill metadata from ClawHub."""
    try:
        result = subprocess.run(
            ["clawhub", "search", skill_name, "--limit", "1"],
            capture_output=True,
            text=True

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/cache-skill.py (reported line 98)May include surrounding context.

python
def fetch_skill_metadata(skill_name):
    """Fetch skill metadata from ClawHub."""
    try:
        result = subprocess.run(
            ["clawhub", "search", skill_name, "--limit", "1"],
            capture_output=True,
            text=True

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

The manifest describes a skill for caching and using remote skills locally, which justifies network and local file operations. Invoking external binaries via subprocess (clawhub search here, and later date) adds command-execution capability that is not clearly necessary for the stated purpose and expands the skill beyond straightforward caching logic.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script downloads remote SKILL.md and related files and writes them directly into the local skills cache with no integrity verification, provenance validation, or explicit safety barrier. Because this repository's purpose is to make remote skills behave like locally installed ones, the context makes the risk higher: users may implicitly trust cached remote content as if it were local and safe.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/cache-skill.py (reported line 184)May include surrounding context.

python
metadata = {
        "name": skill_name,
        "source": source_url,
        "cached_at": subprocess.run(["date", "-Iseconds"], capture_output=True, text=True).stdout.strip(),
        "skill_url": skill_url,
        "version": "cached"
    }

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script creates or replaces a symlink inside the active skills directory, which directly changes local skill resolution and can cause newly downloaded remote content to be used in place of an existing skill. In context, this is particularly risky because the cache is populated from remote sources and the user is only shown success/progress messaging, not a clear warning that system behavior and trust assumptions are being modified.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The module docstring says "Execute a remote skill directly without downloading" and the function docstring says it will "execute a command using the skill's instructions." In reality, the script fetches remote content, writes it to a temporary file, prints part of it, and returns success; it never uses subprocess or otherwise executes the supplied command.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script explicitly disables TLS certificate verification and hostname checking before fetching remote skill content. This allows a man-in-the-middle attacker to spoof the remote source and supply arbitrary SKILL.md instructions, which is especially dangerous in a skill-engine context because users may trust and follow the displayed remote instructions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The network request is performed with TLS protections intentionally disabled and without any warning to the user, so operators may believe they are securely fetching remote metadata when they are not. In the context of a remote skill engine that caches and uses remote skills from GitHub/ClawHub, this increases the danger because tampered metadata can mislead downstream trust decisions and facilitate delivery of malicious remote skills.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script performs live network searches against ClawHub and GitHub, which contradicts the stated offline cache-and-use behavior in the skill metadata. This expands the trust boundary to remote, potentially attacker-controlled content discovery and can expose users to unreviewed skills, tracking, or unexpected network activity when they believe the feature is operating from local cache only.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The script writes fetched remote content to a temporary file, but there is no comment, docstring detail, or advance user notice explaining that a local file will be created. Although temporary, this is still a file write operation covered by the warning requirement for code files.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The GitHub search logic adds broad remote discovery across repositories and code search that goes beyond the stated purpose of caching and using remote skills locally. While not directly executing returned content, this increases exposure to malicious or misleading skill sources and weakens the principle of least functionality for a component that users may expect to be limited to known cached artifacts.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.