-
Notifications
You must be signed in to change notification settings - Fork 46
feat(skills): add clawsec-clawhub-checker reputation checking skill #41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
777ff98
50a2d5f
e6b9e90
269ff94
7652556
6893390
1530958
4538622
6d6bb6a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,133 @@ | ||
| # ClawSec ClawHub Checker | ||
|
|
||
| A ClawSec suite skill that enhances the guarded skill installer with ClawHub reputation checks and VirusTotal Code Insight integration. | ||
|
|
||
| ## Purpose | ||
|
|
||
| Adds a second layer of security to skill installation by: | ||
| 1. Checking ClawHub's VirusTotal Code Insight reputation scores | ||
| 2. Analyzing skill age, author reputation, and download statistics | ||
| 3. Requiring double confirmation for suspicious skills | ||
| 4. Integrating with existing ClawSec advisory checks | ||
|
|
||
| ## Architecture | ||
|
|
||
| ``` | ||
| clawsec-suite (base) | ||
| └── clawsec-clawhub-checker (enhancement) | ||
| ├── enhanced_guarded_install.mjs - Main enhanced installer | ||
| ├── check_clawhub_reputation.mjs - Reputation checking logic | ||
| ├── setup_reputation_hook.mjs - Integration script | ||
| └── hooks/ - Enhanced advisory guardian hook | ||
| ``` | ||
|
|
||
| ## Installation | ||
|
|
||
| ```bash | ||
| # First install the base suite | ||
| npx clawhub install clawsec-suite | ||
|
|
||
| # Then install the checker | ||
| npx clawhub install clawsec-clawhub-checker | ||
|
|
||
| # Run setup to integrate with existing suite | ||
| node scripts/setup_reputation_hook.mjs | ||
|
|
||
| # Restart OpenClaw gateway | ||
| openclaw gateway restart | ||
| ``` | ||
|
|
||
| Setup installs these scripts into `clawsec-suite/scripts`: | ||
| - `enhanced_guarded_install.mjs` | ||
| - `guarded_skill_install_wrapper.mjs` (drop-in wrapper) | ||
| - `check_clawhub_reputation.mjs` | ||
|
|
||
| The original `guarded_skill_install.mjs` remains unchanged. | ||
|
|
||
| ## Usage | ||
|
|
||
| ### Enhanced Guarded Installer | ||
|
|
||
| ```bash | ||
| # Basic usage via wrapper (includes reputation checks) | ||
| node scripts/guarded_skill_install_wrapper.mjs --skill some-skill --version 1.0.0 | ||
|
|
||
| # Direct usage (enhanced script) | ||
| node scripts/enhanced_guarded_install.mjs --skill some-skill --version 1.0.0 | ||
|
|
||
| # With reputation confirmation override | ||
| node scripts/guarded_skill_install_wrapper.mjs --skill suspicious-skill --version 1.0.0 --confirm-reputation | ||
|
|
||
| # Adjust reputation threshold (default: 70) | ||
| node scripts/guarded_skill_install_wrapper.mjs --skill some-skill --reputation-threshold 80 | ||
| ``` | ||
|
|
||
| ### Reputation Check Only | ||
|
|
||
| ```bash | ||
| # Check reputation without installation | ||
| node scripts/check_clawhub_reputation.mjs some-skill 1.0.0 70 | ||
| ``` | ||
|
|
||
| ## Exit Codes | ||
|
|
||
| - `0` - Safe to install | ||
| - `42` - Advisory match found (requires `--confirm-advisory`) | ||
| - `43` - Reputation warning (requires `--confirm-reputation`) - **NEW** | ||
| - `1` - Error | ||
|
|
||
| ## Reputation Signals Checked | ||
|
|
||
| 1. **VirusTotal Code Insight** - Malicious code patterns | ||
| 2. **Skill Age** - New skills (<7 days) are riskier | ||
| 3. **Author Reputation** - Number of published skills | ||
| 4. **Update Frequency** - Stale skills (>90 days) | ||
| 5. **Download Statistics** - Low download counts | ||
| 6. **Version Existence** - Specified version availability | ||
|
|
||
| ## Configuration | ||
|
|
||
| Environment variables: | ||
| - `CLAWHUB_REPUTATION_THRESHOLD` - Minimum score (0-100, default: 70) | ||
|
|
||
| ## Integration Points | ||
|
|
||
| 1. **Enhanced `guarded_skill_install.mjs`** - Wraps original with reputation checks | ||
| via `guarded_skill_install_wrapper.mjs` and `enhanced_guarded_install.mjs` | ||
| 2. **Updated advisory guardian hook** - Adds reputation warnings to alerts | ||
| 3. **Catalog entry in clawsec-suite** - Listed as available enhancement | ||
|
|
||
| ## Development | ||
|
|
||
| ### Files | ||
|
|
||
| - `SKILL.md` - Main documentation | ||
| - `skill.json` - Skill metadata and SBOM | ||
| - `scripts/enhanced_guarded_install.mjs` - Enhanced installer | ||
| - `scripts/check_clawhub_reputation.mjs` - Reputation logic | ||
| - `scripts/setup_reputation_hook.mjs` - Integration script | ||
| - `hooks/clawsec-advisory-guardian/lib/reputation.mjs` - Hook module | ||
|
|
||
| ### Testing | ||
|
|
||
| ```bash | ||
| # Test reputation check | ||
| node scripts/check_clawhub_reputation.mjs clawsec-suite | ||
|
|
||
| # Test enhanced installer (dry run) | ||
| node scripts/enhanced_guarded_install.mjs --skill test-skill --dry-run | ||
|
|
||
| # Test setup | ||
| node scripts/setup_reputation_hook.mjs | ||
| ``` | ||
|
|
||
| ## Security Considerations | ||
|
|
||
| - Reputation checks are **heuristic**, not definitive | ||
| - **False positives** possible with legitimate novel skills | ||
| - Always **review skill code** before overriding warnings | ||
| - This is **defense-in-depth**, not replacement for advisory feeds | ||
|
|
||
| ## License | ||
|
|
||
| MIT - Part of the ClawSec security suite | ||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,149 @@ | ||||||||
| --- | ||||||||
| name: clawsec-clawhub-checker | ||||||||
| version: 0.0.1 | ||||||||
| description: ClawHub reputation checker for ClawSec suite. Enhances guarded skill installer with VirusTotal Code Insight reputation scores and additional safety checks. | ||||||||
| homepage: https://clawsec.prompt.security | ||||||||
| clawdis: | ||||||||
| emoji: "🛡️" | ||||||||
| requires: | ||||||||
| bins: [clawhub, curl, jq] | ||||||||
| depends_on: [clawsec-suite] | ||||||||
| --- | ||||||||
|
|
||||||||
| # ClawSec ClawHub Checker | ||||||||
|
|
||||||||
| Enhances the ClawSec suite's guarded skill installer with ClawHub reputation checks. Adds a second layer of security by checking VirusTotal Code Insight scores and other reputation signals before allowing skill installation. | ||||||||
|
|
||||||||
| ## What It Does | ||||||||
|
|
||||||||
| 1. **Wraps `clawhub install`** - Intercepts skill installation requests | ||||||||
| 2. **Checks VirusTotal reputation** - Uses ClawHub's built-in VirusTotal Code Insight | ||||||||
| 3. **Adds double confirmation** - For suspicious skills (reputation score below threshold) | ||||||||
| 4. **Integrates with advisory feed** - Works alongside existing clawsec-suite advisories | ||||||||
| 5. **Provides detailed reports** - Shows why a skill is flagged as suspicious | ||||||||
|
|
||||||||
| ## Installation | ||||||||
|
|
||||||||
| This skill must be installed **after** `clawsec-suite`: | ||||||||
|
|
||||||||
| ```bash | ||||||||
| # First install the suite | ||||||||
| npx clawhub@latest install clawsec-suite | ||||||||
|
|
||||||||
| # Then install the checker | ||||||||
| npx clawhub@latest install clawsec-clawhub-checker | ||||||||
|
|
||||||||
| # Run the setup script to integrate with clawsec-suite | ||||||||
| node ~/.openclaw/skills/clawsec-clawhub-checker/scripts/setup_reputation_hook.mjs | ||||||||
|
|
||||||||
| # Restart OpenClaw gateway for changes to take effect | ||||||||
| openclaw gateway restart | ||||||||
| ``` | ||||||||
|
|
||||||||
| After setup, the checker adds `enhanced_guarded_install.mjs` and | ||||||||
| `guarded_skill_install_wrapper.mjs` under `clawsec-suite/scripts` and updates the advisory | ||||||||
| guardian hook. The original `guarded_skill_install.mjs` is not replaced. | ||||||||
|
|
||||||||
| ## How It Works | ||||||||
|
|
||||||||
| ### Enhanced Guarded Installer | ||||||||
|
|
||||||||
| After setup, run the wrapper (drop-in path) or the enhanced script directly: | ||||||||
| ```bash | ||||||||
| # Recommended drop-in wrapper | ||||||||
| node scripts/guarded_skill_install_wrapper.mjs --skill some-skill --version 1.0.0 | ||||||||
|
|
||||||||
| # Or call the enhanced script directly | ||||||||
| node scripts/enhanced_guarded_install.mjs --skill some-skill --version 1.0.0 | ||||||||
| ``` | ||||||||
|
|
||||||||
| The enhanced flow: | ||||||||
| 1. **Advisory check** (existing) - Checks clawsec advisory feed | ||||||||
| 2. **Reputation check** (new) - Queries ClawHub for VirusTotal scores | ||||||||
| 3. **Risk assessment** - Combines advisory + reputation signals | ||||||||
| 4. **Double confirmation** - If risky, requires explicit `--confirm-reputation` | ||||||||
|
|
||||||||
| ### Reputation Signals Checked | ||||||||
|
|
||||||||
| 1. **VirusTotal Code Insight** - Malicious code patterns, external dependencies (Docker usage, network calls, eval usage, crypto keys) | ||||||||
| 2. **Skill age & updates** - New skills vs established ones | ||||||||
| 3. **Author reputation** - Other skills by same author | ||||||||
| 4. **Download statistics** - Popularity signals | ||||||||
|
|
||||||||
| ### Exit Codes | ||||||||
|
|
||||||||
| - `0` - Safe to install (no advisories, good reputation) | ||||||||
| - `42` - Advisory match found (existing behavior) | ||||||||
| - `43` - Reputation warning (new - requires `--confirm-reputation`) | ||||||||
| - `1` - Error | ||||||||
|
|
||||||||
|
Comment on lines
+78
to
+79
|
||||||||
| - `1` - Error | |
| - `CLAWHUB_ALLOW_SUSPICIOUS` - Reserved for future use; not currently read by this skill. Intended to allow installation of suspicious skills without confirmation. | |
| - `CLAWHUB_VIRUSTOTAL_API_KEY` - Reserved for future use; not currently read by this skill. Intended for using your own VirusTotal API key for deeper scans. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| import { spawnSync } from "node:child_process"; | ||
| import { fileURLToPath } from "node:url"; | ||
| import path from "node:path"; | ||
|
|
||
| /** | ||
| * Check reputation for a skill | ||
| * @param {string} skillName - Skill name | ||
| * @param {string} version - Skill version | ||
| * @returns {Promise<{safe: boolean, score: number, warnings: string[]}>} | ||
| */ | ||
| export async function checkReputation(skillName, version) { | ||
| const result = { | ||
| safe: true, | ||
| score: 100, | ||
| warnings: [], | ||
| }; | ||
|
|
||
| try { | ||
| // Try to get skill slug from directory name or skill.json | ||
| // For now, use skillName as slug (simplified) | ||
| const skillSlug = skillName.toLowerCase().replace(/[^a-z0-9-]/g, '-'); | ||
|
|
||
| // Run the reputation check script | ||
| // Current file is at: .../hooks/clawsec-advisory-guardian/lib/reputation.mjs | ||
| // We need to go up 3 levels to get to the skill root directory | ||
| const __dirname = path.dirname(fileURLToPath(import.meta.url)); | ||
| const checkerDir = path.resolve(__dirname, '../../..'); | ||
|
|
||
| const reputationCheck = spawnSync( | ||
| "node", | ||
| [ | ||
| `${checkerDir}/scripts/check_clawhub_reputation.mjs`, | ||
| skillSlug, | ||
|
Comment on lines
+29
to
+33
|
||
| version || "", | ||
| "70" // Default threshold | ||
| ], | ||
| { encoding: "utf-8", cwd: checkerDir } | ||
| ); | ||
|
|
||
| if (reputationCheck.status === 0) { | ||
| try { | ||
| const repResult = JSON.parse(reputationCheck.stdout); | ||
| result.safe = repResult.safe; | ||
| result.score = repResult.score; | ||
| result.warnings = repResult.warnings; | ||
| } catch (parseError) { | ||
| result.warnings.push(`Failed to parse reputation result: ${parseError.message}`); | ||
| result.score = 60; | ||
| result.safe = result.score >= 70; | ||
| } | ||
| } else if (reputationCheck.status === 43) { | ||
| // Reputation warning exit code | ||
| try { | ||
| const repResult = JSON.parse(reputationCheck.stdout); | ||
| result.safe = false; | ||
| result.score = repResult.score; | ||
| result.warnings = repResult.warnings; | ||
| } catch { | ||
| result.safe = false; | ||
| result.score = 50; | ||
| result.warnings.push("Skill flagged by reputation check"); | ||
| } | ||
| } else { | ||
| // Error running check | ||
| result.warnings.push(`Reputation check failed: ${reputationCheck.stderr || 'Unknown error'}`); | ||
| result.score = 60; | ||
| result.safe = result.score >= 70; | ||
| } | ||
| } catch (error) { | ||
| result.warnings.push(`Reputation check error: ${error.message}`); | ||
| result.score = 50; | ||
| result.safe = result.score >= 70; | ||
| } | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| /** | ||
| * Format reputation warning for alert messages | ||
| * @param {{score: number, warnings: string[]}} reputationInfo | ||
| * @returns {string} | ||
| */ | ||
| export function formatReputationWarning(reputationInfo) { | ||
| if (!reputationInfo || reputationInfo.score >= 70) return ""; | ||
|
|
||
| const lines = [ | ||
| `\n⚠️ **REPUTATION WARNING** (Score: ${reputationInfo.score}/100)`, | ||
| ]; | ||
|
|
||
| if (reputationInfo.warnings.length > 0) { | ||
| lines.push(""); | ||
| reputationInfo.warnings.forEach(w => lines.push(`• ${w}`)); | ||
| } | ||
|
|
||
| lines.push(""); | ||
| lines.push("This skill has low reputation score. Review carefully before installation."); | ||
|
|
||
| return lines.join("\n"); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
README.md lists
CLAWHUB_ALLOW_SUSPICIOUSas a supported environment variable, but none of the scripts read it. Either implement the behavior or remove it from the docs to avoid misleading configuration guidance.