Skill flagged — suspicious patterns detected

ClawHub Security flagged this skill as suspicious. Review the scan results before using.

Skill Advisor

v1.1.0

Evaluate OpenClaw skills before installation. Use when user wants to check a skill's safety, dependencies, popularity, or get an installation recommendation....

0· 125·0 current·0 all-time

Install

OpenClaw Prompt Flow

Install with OpenClaw

Best for remote or guided setup. Copy the exact prompt, then paste it into OpenClaw for tobewin/skill-advisor.

Previewing Install & Setup.
Prompt PreviewInstall & Setup
Install the skill "Skill Advisor" (tobewin/skill-advisor) from ClawHub.
Skill page: https://clawhub.ai/tobewin/skill-advisor
Keep the work scoped to this skill only.
After install, inspect the skill metadata and help me finish setup.
Required binaries: curl
Use only the metadata you can verify from ClawHub; do not invent missing requirements.
Ask before making any broader environment changes.

Command Line

CLI Commands

Use the direct CLI path if you want to install manually and keep every step visible.

OpenClaw CLI

Bare skill slug

openclaw skills install skill-advisor

ClawHub CLI

Package manager switcher

npx clawhub@latest install skill-advisor
Security Scan
VirusTotalVirusTotal
Suspicious
View report →
OpenClawOpenClaw
Benign
high confidence
Purpose & Capability
Name/description match the actual behavior: SKILL.md instructs the agent to fetch skill metadata and SKILL.md from ClawHub and produce an assessment. Required binary (curl) is appropriate and proportional.
Instruction Scope
Instructions direct network fetches of arbitrary skill metadata and SKILL.md from ClawHub and run local Python parsing. This is expected for an advisor tool, but fetching and processing arbitrary remote content can expose the agent to untrusted inputs (e.g., misleading SKILL.md text, URLs). The skill does not instruct reading unrelated local files or exfiltrating secrets.
Install Mechanism
No install spec and no code files beyond SKILL.md and a license — lowest-risk delivery model (instruction-only). Nothing is downloaded or written by an installer.
Credentials
No environment variables, credentials, or config paths are required. The lack of requested secrets is proportionate to the stated purpose. Note: if the platform's ClawHub API required authentication in practice, that would be a separate credential consideration (not declared here).
Persistence & Privilege
always:false and no special privileges or modifications to other skills or system settings. The skill does not request permanent agent presence beyond normal invocation.
Assessment
This skill appears coherent and low-risk because it is instruction-only and only uses curl to fetch ClawHub skill metadata. Before using it: (1) confirm your agent/platform does not require providing any ClawHub API keys — if an API key is later needed, evaluate whether that credential is appropriate to share; (2) treat its output as advisory: manually inspect any fetched SKILL.md and metadata for suspicious links or hidden endpoints; (3) avoid allowing the agent to fetch private or internal skill names that could expose internal data; and (4) do not rely solely on automated conclusions—use the report to guide a manual review. If you want higher assurance, test the skill with a well-known public skill name first and inspect the network activity logs.

Like a lobster shell, security has layers — review code before you run it.

Runtime requirements

🔍 Clawdis
Binscurl
latestvk975eekbevqtqh1t49b68m72cd83ftp9
125downloads
0stars
2versions
Updated 1mo ago
v1.1.0
MIT-0

Skill Advisor

Pre-install assessment tool for OpenClaw skills. Generate comprehensive evaluation reports to help users decide whether to install a skill.

Features

  • 🔒 Security Status: Check ClawHub official scan results
  • 📊 Popularity Metrics: Downloads, stars, install count
  • 🔄 Maintenance Status: Last update time, activity level
  • 📦 Dependency Analysis: Required tools, libraries, complexity
  • 💰 API Cost Assessment: Free/paid API requirements
  • 🎯 Installation Recommendation: Clear go/no-go guidance

Trigger Conditions

  • "Check this skill before installing" / "安装前检查这个skill"
  • "Is {skill-name} safe?" / "{skill-name}安全吗"
  • "Evaluate skill {skill-name}" / "评估skill {skill-name}"
  • "What does {skill-name} need?" / "{skill-name}需要什么依赖"
  • "Should I install {skill-name}?" / "要不要安装{skill-name}"
  • "skill-advisor {skill-name}"
  • "帮我看看这个skill怎么样"

Language Support

This skill supports multiple languages. Output language automatically matches the user's conversation language with OpenClaw.

Supported Languages:

  • 中文 (Chinese)
  • English

Detection:

  • If user writes in Chinese → Output Chinese report
  • If user writes in English → Output English report
  • Default: Match the user's input language

Step 1: Get Skill Information

When user provides a skill name, fetch its metadata:

SKILL_NAME="user-provided-skill-name"

# Get skill metadata from ClawHub
echo "📡 Fetching skill information..."
clawhub inspect "$SKILL_NAME" 2>/dev/null

# Alternative: Use ClawHub API directly
curl -s "https://clawhub.ai/api/v1/skills/$SKILL_NAME" | python3 -m json.tool 2>/dev/null

Step 2: Fetch SKILL.md Content

Get the actual SKILL.md to analyze dependencies and functionality:

# Fetch SKILL.md content
SKILL_CONTENT=$(curl -s "https://clawhub.ai/api/v1/skills/$SKILL_NAME" | python3 -c "
import sys, json
try:
    data = json.load(sys.stdin)
    if 'skill' in data and 'content' in data['skill']:
        print(data['skill']['content'])
    elif 'content' in data:
        print(data['content'])
    else:
        print('CONTENT_NOT_FOUND')
except:
    print('PARSE_ERROR')
" 2>/dev/null)

echo "$SKILL_CONTENT"

Step 3: Analyze and Generate Report

Parse the skill data and generate the assessment report in the user's language:

python3 << 'PYEOF'
import json
import re
import sys
from datetime import datetime

# Detect user language from input (passed as argument)
USER_LANG = "en"  # Default to English, will be overridden by agent

# Simulated skill data (replace with actual API response)
skill_data = {
    "name": "SKILL_NAME_PLACEHOLDER",
    "description": "DESCRIPTION_PLACEHOLDER",
    "version": "1.0.0",
    "owner": "AUTHOR_PLACEHOLDER",
    "created_at": "2026-01-01T00:00:00Z",
    "updated_at": "2026-03-20T00:00:00Z",
    "downloads": 0,
    "stars": 0,
    "license": "MIT-0",
    "security_status": "unknown"
}

skill_content = """
SKILL_MD_CONTENT_PLACEHOLDER
"""

# Labels for different languages
LABELS = {
    "zh": {
        "conclusion_header": "🎯 结论",
        "recommend_install": "✅ 推荐安装",
        "caution_install": "⚠️ 可以安装,请注意事项",
        "not_recommend": "❌ 不建议安装",
        "score": "综合评分",
        "security_pass": "通过",
        "security_review": "需审查",
        "deps_light": "轻量",
        "deps_heavy": "较重",
        "report_title": "📋 Skill 评估报告",
        "metrics": "综合指标",
        "official_security": "🔒 官方安全",
        "benign": "✅ Benign(ClawHub扫描通过)",
        "suspicious": "⚠️ Suspicious(需要审查)",
        "security_unknown": "❓ 未知(未扫描)",
        "popularity": "📈 流行度",
        "downloads": "downloads",
        "stars": "stars",
        "maintenance": "🔄 维护状态",
        "active_maintain": "天前更新(活跃维护)",
        "normal_maintain": "天前更新(正常维护)",
        "less_maintain": "天前更新(维护较少)",
        "stop_maintain": "天前更新(可能停止维护)",
        "maintenance_unknown": "❓ 未知",
        "dep_burden": "📦 依赖负担",
        "no_dep": "无需额外依赖",
        "light_dep": "轻量",
        "heavy_dep": "较重",
        "deps_count": "个依赖",
        "api_cost": "💰 API成本",
        "no_api": "无需外部API",
        "api_required": "需要",
        "description": "📝 功能说明",
        "env_req": "⚙️ 环境要求",
        "cli_tools": "命令行工具",
        "python_pkg": "Python包",
        "node_pkg": "Node包",
        "api_key": "API密钥",
        "no_special_req": "无特殊要求",
        "usage_note": "⚠️ 使用注意",
        "data_upload": "📤 文档/数据会上传到",
        "external_service": "📤 会访问外部服务",
        "sensitive_data": "🔐 敏感数据请谨慎处理",
        "install_advice": "💡 安装建议",
        "safe_install": "可安全安装。",
        "caution_install_text": "可以安装,但请注意上述事项。",
        "not_install_text": "不建议安装,请寻找替代方案。",
        "need_config": "需要配置API Key",
        "meta_info": "ℹ️ 元信息",
        "author": "作者",
        "version": "版本",
        "license": "许可证",
        "score_time": "评分时间",
    },
    "en": {
        "conclusion_header": "🎯 Conclusion",
        "recommend_install": "✅ Recommended",
        "caution_install": "⚠️ Install with Caution",
        "not_recommend": "❌ Not Recommended",
        "score": "Overall Score",
        "security_pass": "Passed",
        "security_review": "Review Needed",
        "deps_light": "Light",
        "deps_heavy": "Heavy",
        "report_title": "📋 Skill Assessment Report",
        "metrics": "Metrics",
        "official_security": "🔒 Official Security",
        "benign": "✅ Benign (ClawHub scan passed)",
        "suspicious": "⚠️ Suspicious (needs review)",
        "security_unknown": "❓ Unknown (not scanned)",
        "popularity": "📈 Popularity",
        "downloads": "downloads",
        "stars": "stars",
        "maintenance": "🔄 Maintenance",
        "active_maintain": "days ago (actively maintained)",
        "normal_maintain": "days ago (normal maintenance)",
        "less_maintain": "days ago (less maintained)",
        "stop_maintain": "days ago (possibly abandoned)",
        "maintenance_unknown": "❓ Unknown",
        "dep_burden": "📦 Dependencies",
        "no_dep": "No dependencies required",
        "light_dep": "Light",
        "heavy_dep": "Heavy",
        "deps_count": "dependencies",
        "api_cost": "💰 API Cost",
        "no_api": "No external API required",
        "api_required": "Requires",
        "description": "📝 Description",
        "env_req": "⚙️ Requirements",
        "cli_tools": "CLI Tools",
        "python_pkg": "Python Packages",
        "node_pkg": "Node Packages",
        "api_key": "API Keys",
        "no_special_req": "No special requirements",
        "usage_note": "⚠️ Usage Notes",
        "data_upload": "📤 Data uploads to",
        "external_service": "📤 Accesses external services",
        "sensitive_data": "🔐 Handle sensitive data with care",
        "install_advice": "💡 Installation Advice",
        "safe_install": "Safe to install.",
        "caution_install_text": "Can be installed, but please note the above.",
        "not_install_text": "Not recommended. Consider alternatives.",
        "need_config": "API Key configuration required",
        "meta_info": "ℹ️ Metadata",
        "author": "Author",
        "version": "Version",
        "license": "License",
        "score_time": "Scored at",
    }
}

def get_label(key, lang="en"):
    """Get localized label"""
    return LABELS.get(lang, LABELS["en"]).get(key, key)

def calculate_security_score(content, security_status):
    score = 100
    if security_status == "benign":
        return 100
    elif security_status == "suspicious":
        return 50
    
    dangerous_patterns = [
        (r'curl\s+-fsSL.*\|.*bash', 30),
        (r'sudo\s+(apt|yum|dnf)\s+install', 15),
        (r'eval\s*\(', 20),
        (r'exec\s*\(', 15),
    ]
    
    for pattern, penalty in dangerous_patterns:
        if re.search(pattern, content, re.IGNORECASE):
            score -= penalty
    
    return max(0, score)

def calculate_popularity_score(downloads, stars):
    score = 0
    if downloads >= 10000: score += 60
    elif downloads >= 1000: score += 50
    elif downloads >= 100: score += 40
    elif downloads >= 10: score += 30
    else: score += 20
    
    if stars >= 50: score += 40
    elif stars >= 10: score += 30
    elif stars >= 1: score += 20
    else: score += 10
    
    return score

def calculate_maintenance_score(updated_at):
    try:
        last_update = datetime.fromisoformat(updated_at.replace('Z', '+00:00'))
        now = datetime.now(last_update.tzinfo)
        days = (now - last_update).days
        
        if days <= 7: return 100
        elif days <= 30: return 80
        elif days <= 90: return 60
        else: return 40
    except:
        return 50

def extract_dependencies(content):
    deps = {"bins": [], "env_vars": [], "pip_packages": [], "npm_packages": [], "complexity": "unknown"}
    
    bins_match = re.search(r'"bins"\s*:\s*\[(.*?)\]', content)
    if bins_match:
        deps["bins"] = [b.strip().strip('"') for b in bins_match.group(1).split(',') if b.strip()]
    
    env_match = re.search(r'"env"\s*:\s*\[(.*?)\]', content)
    if env_match:
        deps["env_vars"] = [e.strip().strip('"') for e in env_match.group(1).split(',') if e.strip()]
    
    pip_patterns = re.findall(r'pip\s+install\s+([\w-]+)', content)
    deps["pip_packages"] = list(set(pip_patterns))
    
    npm_patterns = re.findall(r'npm\s+(?:install|i)\s+(?:-g\s+)?([\w-]+)', content)
    deps["npm_packages"] = list(set(npm_patterns))
    
    lines = len(content.split('\n'))
    if lines < 100: deps["complexity"] = "simple"
    elif lines < 250: deps["complexity"] = "medium"
    else: deps["complexity"] = "complex"
    
    return deps

def calculate_dependency_score(deps):
    score = 100
    bin_count = len(deps["bins"])
    if bin_count <= 2: score -= 10
    elif bin_count <= 4: score -= 20
    elif bin_count > 4: score -= 30
    
    pkg_count = len(deps["pip_packages"]) + len(deps["npm_packages"])
    if pkg_count > 5: score -= 20
    elif pkg_count > 0: score -= 10
    
    return max(0, score)

def calculate_api_cost_score(deps, content):
    if not deps["env_vars"]:
        return 100
    
    free_indicators = ["免费", "free", "免费额度", "new user", "free tier"]
    has_free = any(indicator in content.lower() for indicator in free_indicators)
    
    return 80 if has_free else 60

def generate_report(skill_data, skill_content, lang="en"):
    L = lambda k: get_label(k, lang)
    
    name = skill_data.get("name", "unknown")
    description = skill_data.get("description", "No description")
    version = skill_data.get("version", "?.?.?")
    owner = skill_data.get("owner", "unknown")
    downloads = skill_data.get("downloads", 0)
    stars = skill_data.get("stars", 0)
    updated_at = skill_data.get("updated_at", "")
    security_status = skill_data.get("security_status", "unknown")
    license_type = skill_data.get("license", "unknown")
    
    security_score = calculate_security_score(skill_content, security_status)
    popularity_score = calculate_popularity_score(downloads, stars)
    maintenance_score = calculate_maintenance_score(updated_at)
    deps = extract_dependencies(skill_content)
    dependency_score = calculate_dependency_score(deps)
    api_cost_score = calculate_api_cost_score(deps, skill_content)
    
    total_score = (
        security_score * 0.30 +
        popularity_score * 0.25 +
        maintenance_score * 0.20 +
        dependency_score * 0.15 +
        api_cost_score * 0.10
    )
    
    if total_score >= 80:
        grade = "A"
        recommendation = L("recommend_install")
        rec_icon = "✅"
    elif total_score >= 60:
        grade = "B"
        recommendation = L("caution_install")
        rec_icon = "⚠️"
    else:
        grade = "C"
        recommendation = L("not_recommend")
        rec_icon = "❌"
    
    if security_status == "benign":
        security_text = L("benign")
    elif security_status == "suspicious":
        security_text = L("suspicious")
    else:
        security_text = L("security_unknown")
    
    try:
        last_update = datetime.fromisoformat(updated_at.replace('Z', '+00:00'))
        now = datetime.now(last_update.tzinfo)
        days = (now - last_update).days
        if days <= 7:
            maintenance_text = f"✅ {days}{L('active_maintain')}"
        elif days <= 30:
            maintenance_text = f"✅ {days}{L('normal_maintain')}"
        elif days <= 90:
            maintenance_text = f"⚠️ {days}{L('less_maintain')}"
        else:
            maintenance_text = f"⚠️ {days}{L('stop_maintain')}"
    except:
        maintenance_text = L("maintenance_unknown")
    
    all_deps = deps["bins"] + deps["pip_packages"] + deps["npm_packages"]
    if not all_deps:
        deps_text = L("no_dep")
    elif len(all_deps) <= 3:
        deps_text = f"{L('light_dep')}({', '.join(all_deps)})"
    else:
        deps_text = f"{L('heavy_dep')}({len(all_deps)}{L('deps_count')})"
    
    if not deps["env_vars"]:
        api_text = L("no_api")
    else:
        api_text = f"{L('api_required')} {', '.join(deps['env_vars'])}"
    
    data_warnings = []
    if "api.siliconflow.cn" in skill_content or "siliconflow" in skill_content.lower():
        data_warnings.append(f"{L('data_upload')} api.siliconflow.cn")
    if "curl" in skill_content and "https://" in skill_content:
        urls = re.findall(r'https?://[^\s"\'\)]+', skill_content)
        external_domains = set()
        for url in urls:
            if "clawhub" not in url and "github" not in url and "openclaw" not in url:
                domain = url.split("//")[1].split("/")[0]
                external_domains.add(domain)
        if external_domains:
            data_warnings.append(f"{L('external_service')}:{', '.join(list(external_domains)[:3])}")
    
    report = f"""
┌─────────────────────────────────────────────────────────┐
│  {L('conclusion_header')}:{rec_icon} {recommendation.ljust(30)}│
│  {L('score')}:{total_score:.0f}/100 ({grade}级) | {L('official_security').replace('🔒 ', '')}:{L('security_pass') if security_score >= 80 else L('security_review')} | {L('dep_burden').replace('📦 ', '')}:{L('deps_light') if dependency_score >= 80 else L('deps_heavy')}           │
└─────────────────────────────────────────────────────────┘

━━━ {L('report_title')}:{name} ━━━━━━━━━━━━━━━━━━━━━━━━━

📊 {L('metrics')}
├─ {L('official_security')}:{security_text}
├─ {L('popularity')}:⭐ {downloads} {L('downloads')} | ⭐ {stars} {L('stars')}
├─ {L('maintenance')}:{maintenance_text}
├─ {L('dep_burden')}:{deps_text}
└─ {L('api_cost')}:{api_text}

{L('description')}
{description[:150]}{'...' if len(description) > 150 else ''}

{L('env_req')}"""

    if deps["bins"]:
        report += f"\n├─ {L('cli_tools')}:{', '.join(deps['bins'])}"
    if deps["pip_packages"]:
        report += f"\n├─ {L('python_pkg')}:{', '.join(deps['pip_packages'])}"
    if deps["npm_packages"]:
        report += f"\n├─ {L('node_pkg')}:{', '.join(deps['npm_packages'])}"
    if deps["env_vars"]:
        report += f"\n└─ {L('api_key')}:{', '.join(deps['env_vars'])}"
    elif not deps["bins"] and not deps["pip_packages"] and not deps["npm_packages"]:
        report += f"\n└─ {L('no_special_req')}"

    if data_warnings:
        report += f"\n\n{L('usage_note')}"
        for warning in data_warnings:
            report += f"\n├─ {warning}"
        report += f"\n└─ {L('sensitive_data')}"

    report += f"\n\n{L('install_advice')}"
    if total_score >= 80:
        report += f"\n{L('safe_install')}"
    elif total_score >= 60:
        report += f"\n{L('caution_install_text')}"
    else:
        report += f"\n{L('not_install_text')}"
    
    if deps["env_vars"]:
        report += f"\n{L('need_config')}:{', '.join(deps['env_vars'])}"
    
    report += f"""
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

{L('meta_info')}
├─ {L('author')}:{owner}
├─ {L('version')}:{version}
├─ {L('license')}:{license_type}
└─ {L('score_time')}:{datetime.now().strftime('%Y-%m-%d %H:%M')}
"""
    
    return report

# Example usage - English
print("=== English Report ===")
print(generate_report(skill_data, skill_content, "en"))

print("\n\n=== 中文报告 ===")
print(generate_report(skill_data, skill_content, "zh"))
PYEOF

Step 4: Output Report

The report is displayed directly to the user. No files are created.

🎯 结论:✅ 推荐安装
综合评分:85/100 (A级) | 安全:通过 | 依赖:轻量

━━━ 📋 Skill 评估报告:{skill-name} ━━━━━━━━━━━━━━━━━
...

Usage Flow

User (Chinese): "帮我看看 china-doc-ocr 这个skill怎么样"

Agent:
1. Detect user language → Chinese
2. Run: clawhub inspect china-doc-ocr
3. Fetch SKILL.md content from ClawHub API
4. Parse and analyze
5. Generate report in Chinese
6. Display report to user

---

User (English): "Is skill-xyz safe to install?"

Agent:
1. Detect user language → English
2. Run: clawhub inspect skill-xyz
3. Fetch SKILL.md content from ClawHub API
4. Parse and analyze
5. Generate report in English
6. Display report to user

Error Handling

Skill not found        → "❌ 未找到该skill,请检查名称"
ClawHub API error      → "❌ 无法连接ClawHub,请稍后重试"
Parse error            → "⚠️ 部分信息解析失败,报告可能不完整"

Notes

  • No files are generated (pure text output)
  • Report shows conclusion first, then details
  • Security status uses ClawHub's official scan results
  • Scores are calculated dynamically based on multiple factors
  • All data fetched in real-time from ClawHub

Comments

Loading comments...