Back to skill

Security audit

Skill Vetter

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed skill-auditing tool, but confirmed scanner flaws could let unsafe skills look acceptable in CI or machine-readable reports.

Install only if you treat this as an advisory helper, not a trusted security gate. Do not rely on its CI exit code or verdict_code alone, and manually review markdown instructions, excluded files, and any target skill that uses severity-cap or engine-class metadata.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/audit.py:641
Finding

Target-Controlled Severity Caps Allow Critical Findings to Pass CI

Content
View full analysis
tuple[str | None, int]: skill_md = skill_path / "SKILL.md" if not skill_md.exists(): return None, 0 try: text = skill_md.read_text(encoding="utf-8", errors="replace") except Exception: return None, 0 fm = parse_frontmatter(text) if not fm: return None, 0 cap = None if fm.get("engine-class") is True or fm.get("engine-class") == "true": cap = "high" if "severity-cap" in fm: cap_val = str(fm["severity-cap"]).lower() if cap_val in SEVERITY_ORDER: cap = cap_val if not cap: return None, 0 cap_rank = SEVERITY_ORDER[cap] downgraded = 0 for f in findings: if SEVERITY_ORDER[f["severity"]] > cap_rank: old_severity = f["severity"] f["severity"] = cap f["original_severity"] = f.get("original_severity", old_severity) downgraded += 1 return cap, downgraded ``` ```python "verdict_code": "fail" if by_severity["critical"] > 0 else ( "caution" if by_severity["high"] > 0 else ( "review" if by_severity["medium"] > 0 else "ok" ) ), ``` ```python if args.exit_code: max_severity = "info" for sev, cnt in report["summary"]["by_severity"].items(): if cnt > 0 and SEVERITY_ORDER[sev] > SEVERITY_ORDER[max_severity]: max_severity = sev sys.exit(SEVERITY_EXIT[max_severity]) ``` ### Technical Analysis The scanner reads `severity-cap` and `engine-class` from the target Skill's own `SKILL.md`. It then mutates every finding's effective `severity` before constructing the report. The human-readable primary verdict attempts to compensate by c ...[truncated 1773 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/audit.py:228
Finding

Markdown Code Blocks and Tables Are Excluded from Security Scanning

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/audit.py:190
Finding

Filename and Directory Exclusions Allow Malicious Files to Evade Scanning

Content
View full analysis
= 2 and rel.parts[0] == "references" and rel.name.startswith("_"): continue target_files.append(f) ``` ### Technical Analysis The scanner excludes every file whose basename is `audit.py`, regardless of its resolved location or identity. It also excludes the entire `scripts/patterns/` subtree using string matching. These exclusions are intended to prevent self-referential findings when the scanner audits itself. They are nevertheless applied to every untrusted target Skill. Because the target controls filenames and directory structure, an attacker can deliberately place executable code in an excluded location. The exclusion of `references/_*.md` creates an additional documentation blind spot, although the most direct executable bypass is the global `audit.py` basename exclusion. ### Attack Path 1. An attacker stores malicious executable code in one of the excluded locations, for example: ```text malicious-skill/ ├── SKILL.md └── scripts/ └── audit.py ``` 2. `rglob("*.py ...[truncated 875 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/batch_audit.sh:27
Finding

Batch Audit Fails Open on Scanner Errors and Corrupts Paths Containing Whitespace

Content
View full analysis
/dev/null || echo '{"summary":{"by_severity":{}}}') # 解析 summary=$(echo "$json" | python3 -c " import sys, json try: r = json.load(sys.stdin) s = r['summary']['by_severity'] crit = s.get('critical', 0) high = s.get('high', 0) med = s.get('medium', 0) low = s.get('low', 0) info = s.get('info', 0) v = r.get('verdict_code', 'unknown') print(f'{crit}|{high}|{med}|{low}|{info}|{v}') except Exception as e: print('0|0|0|0|0|error') " 2>/dev/null) IFS='|' read -r crit high med low info vc <<< "$summary" ``` ### Technical Analysis `SKILLS=($(...))` performs unquoted command-substitution expansion. Bash applies word splitting and pathname expansion to the output, so a valid Skill path containing spaces or other shell separators is split into multiple array elements. Separately, scanner failures are converted into a fabricated JSON document with an empty severity map. Standard error is discarded. The parser then represents failures as zero findings and an error verdict, but the script does not return a failing final status for these errors. This is fail-open behavior in security automation: inability to scan a target is not treated as a security failure. ### Attack Path 1. A Skill is placed under a path containing whitespace, or an input causes `audit.py` to fail. 2. During deduplication, the path is split into incorrect array elements, or the scanner exits unsuccessfully. 3. S ...[truncated 756 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
README.md:69
Finding

CI Setup Installs an Unpinned Third-Party Dependency

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (39)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The code is related to skill auditing, so the overall domain matches. However, the declared description presents a feature-rich auditor with specific capabilities (38 rules, JSON reporting, CI exit codes, waiver mechanism, severity-cap adaptation). This code chunk is only a batch reporting wrapper around another script (audit.py): it discovers skill directories in fixed locations, runs the Python auditor, parses JSON, and prints a console summary. JSON is consumed internally rather than emitted as a report artifact here, and several advertised features are not present in the supplied code. Because the actual behavior is materially narrower and includes a hard-coded batch scan behavior not reflected in the description, this is a description-behavior mismatch.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 26)May include surrounding context.

md
python3 scripts/audit.py /path/to/skill

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 29)May include surrounding context.

md
python3 scripts/audit.py /path/to/skill

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 32)May include surrounding context.

md
python3 scripts/audit.py /path/to/skill

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 35)May include surrounding context.

md
python3 scripts/audit.py /path/to/skill

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 114)May include surrounding context.

md
python3 scripts/audit.py /path/to/skill

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 116)May include surrounding context.

md
python3 scripts/audit.py /path/to/skill

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 210)May include surrounding context.

md
python3 scripts/audit.py /path/to/skill

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/_rules_documentation.md (reported line 35)May include surrounding context.

  • SEC-CRED-001 硬编码 API key / secret / password
  • SEC-CRED-002 AWS Access Key ID
  • SEC-CRED-003 私钥头 (BEGIN RSA / OPENSSH / PRIVATE)
  • SEC-CRED-004 敏感路径 (~/.../id_rsa, ~/.../.aws/credentials 等)
  • SEC-CRED-005 1Password op:// URI 误报豁免
  • SEC-CRED-006 环境变量批量读取
text

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/_rules_documentation.md (reported line 52)May include surrounding context.

text
- SEC-SYS-001  sudo / rm -rf
- SEC-SYS-002  chmod 777
- SEC-SYS-003  dd 覆写

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/patterns.md (reported line 64)May include surrounding context.

text
- SEC-SYS-001  sudo / rm -rf
- SEC-SYS-002  chmod 777
- SEC-SYS-003  dd 覆写

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/_rules_documentation.md (reported line 97)May include surrounding context.

md
- QUAL-001  frontmatter 必填字段
- QUAL-002  YAML 解析
- QUAL-003  name 格式(kebab-case)
- QUAL-004  禁用文件(.env / 私钥等)
- QUAL-005  license 声明
- QUAL-006  scripts 可执行权限
- QUAL-007  使用示例

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/patterns/red_flags.yml (reported line 109)May include surrounding context.

yaml
regex: |-
        (?i)(password|passwd|pwd)\s*[:=]\s*["\'][^"\']{4,}["\']
      description: "硬编码密码字符串"
      exception_pattern: '\$\{?[A-Z_]+\}?|op://|vault://|secret://|keychain://'

    - id: SEC-CRED-003
      category: credentials

Credential Access

High
Category
Privilege Escalation
Confidence
80% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/patterns/red_flags.yml (reported line 129)May include surrounding context.

yaml
category: credentials
      name: "访问敏感路径"
      severity: high
      regex: '(~/\.ssh|~/\.aws|~/\.config|~/\.kube|~/\.docker|~/.netrc|\.pem|\.key\b|\.p12|\.pfx)'
      description: "代码引用敏感凭据文件路径"
      note: "需人工评估是否合理(如 SSH key 操作类技能合理)"

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · scripts/patterns/red_flags.yml (reported line 191)May include surrounding context.

yaml
- id: SEC-SYS-003
      category: privilege
      name: "chmod 777 全开"
      severity: medium
      regex: '\bchmod\s+777\b'
      description: "777 权限违反最小权限原则"

Lp1

High
Category
MCP Least Privilege
Confidence
75% confidence
Finding

The skill uses 'shell' capability that is not listed in its permissions. This may indicate deceptive intent or missing permission declarations.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
100% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · scripts/scan.sh (reported line 91)May include surrounding context.

sh
scan "硬编码凭据"             '(api[_-]?key|secret|password|token)\s*[:=]\s*["\x27][^"\x27\s]{8,}'  # safe-pattern: rule-description
scan "外发 curl/wget"         '\b(curl|wget)\s+'  # safe-pattern: rule-description
scan "base64 解码"            '\bbase64\s*(-d|--decode|decode)\b'  # safe-pattern: rule-description
scan "rm -rf / sudo"          '\brm\s+-[rRf]+|sudo\s'  # safe-pattern: rule-description
scan "硬编码 IP"              '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b'  # safe-pattern: rule-description

echo ""

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
100% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · scripts/scan.sh (reported line 91)May include surrounding context.

sh
scan "硬编码凭据"             '(api[_-]?key|secret|password|token)\s*[:=]\s*["\x27][^"\x27\s]{8,}'  # safe-pattern: rule-description
scan "外发 curl/wget"         '\b(curl|wget)\s+'  # safe-pattern: rule-description
scan "base64 解码"            '\bbase64\s*(-d|--decode|decode)\b'  # safe-pattern: rule-description
scan "rm -rf / sudo"          '\brm\s+-[rRf]+|sudo\s'  # safe-pattern: rule-description
scan "硬编码 IP"              '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b'  # safe-pattern: rule-description

echo ""

YARA rule 'agent_skill_destructive_autonomous_actions': Autonomous destructive filesystem, shell history, or repository actions in AI agent skills [agent_skills]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · scripts/scan.sh (reported line 91)May include surrounding context.

sh
'\beval\s*\(|exec(?:Sync)?\s*\('  # safe-pattern: rule-description
scan "硬编码凭据"             '(api[_-]?key|secret|password|token)\s*[:=]\s*["\x27][^"\x27\s]{8,}'  # safe-pattern: rule-description
scan "外发 curl/wget"         '\b(curl|wget)\s+'  # safe-pattern: rule-description
scan "base64 解码"            '\bbase64\s*(-d|--decode|decode)\b'  # safe-pattern: rule-description
scan "rm -rf / sudo"          '\brm\s+-[rRf]+|sudo\s'  # safe-pattern: rule-description
scan "硬编码 IP"              '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b'  # safe-pattern: rule-description

echo ""
echo "═══════════════════════════════════════════════════════"
echo "Findings (grep): $findings"
echo "═══════════════════════════════════════════════════════"

[[ $EXIT_CODE -eq 1 && $fin

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The description advertises trigger phrases including "安全审计", "扫描 skill", and "skill 检查" without defining any activation boundaries or exclusions. These phrases are fairly generic in conversation about skills and could cause unintended invocation because the file does not provide negative examples or a narrower context for when the skill should activate.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This JSON template includes natural-language fields such as "eval() 调用" and a Chinese description, which imposes a specific language in generated output. The file provides no indication that Chinese output is optional, user-selected, or justified by a region-specific requirement.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/_rules_documentation.md (reported line 51)May include surrounding context.

SYS — 系统权限(3 条 · critical)

text
- SEC-SYS-001  sudo / rm -rf
- SEC-SYS-002  chmod 777
- SEC-SYS-003  dd 覆写

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/_rules_documentation.md (reported line 52)May include surrounding context.

text
- SEC-SYS-001  sudo / rm -rf
- SEC-SYS-002  chmod 777
- SEC-SYS-003  dd 覆写

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The title and the substantive procedural content are written in Chinese, which effectively imposes a specific language on users reading the skill reference. The file does not state that the protocol is region-specific or provide an opt-in/alternative language, so this is a natural-language locale policy concern under the stated rule.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/audit_protocol.md (reported line 21)May include surrounding context.

md
**v2.0 工具辅助**:
- ClawHub:`openclaw skills verify <name>` 看元数据
- GitHub:`https://api.github.com/repos/OWNER/REPO` 看 stars/forks/updated

**信任层级**(v1.0 沿用):
1. **OpenClaw 官方技能** → 低审视(仍要 review)

Static analysis

No suspicious patterns detected.