T03 · Remote Payload Retrieval and Execution
- 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: HighVulnerable 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.
