Back to skill

Security audit

Skill Security Scanner

Security checks for vulnerabilities and agentic risk

Overview

This is a local skill scanner with no evident data theft or hidden persistence, but its safety ratings are much stronger than its actual checks support.

Review this skill before relying on it. It appears to be a local, user-triggered scanner rather than malware, but its results should be treated as a lightweight lint signal only, not a reliable security verdict for installing untrusted skills.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/scan-skill.sh:16
Finding
Security scan excludes executable and auxiliary files<![CDATA[ ## Vulnerability Details **File Location**: `scripts/scan-skill.sh:16-20, 32-40` **Vulnerability Type**: Incomplete security scan coverage **Risk Level**: High ### Vulnerable Code ```bash SKILL_NAME=$(basename "$SKILL_PATH") SKILL_FILE="$SKILL_PATH/SKILL.md" if [ ! -f "$SKILL_FILE" ]; then echo "Error: SKILL.md not found in $SKILL_PATH" exit 1 fi echo "🔍 Scanning: $SKILL_NAME" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" # Check for suspicious patterns (in actual code, not examples) ISSUES=() GREEN_FLAGS=() # Network exfiltration - look for actual calls, not examples if grep -qE "^\s*(curl|wget|fetch|axios).*https?://" "$SKILL_FILE" 2>/dev/null; then if ! grep -qE "api\.(github|openclaw)" "$SKILL_FILE" 2>/dev/null; then ISSUES+=("[MEDIUM] Makes network calls to external domains") fi fi # Check metadata for env vars requesting secrets if grep -qE "env:.*(KEY|TOKEN|SECRET|PASSWORD)" "$SKILL_FILE" 2>/dev/null; then ``` ### Technical Analysis The scanner assigns `SKILL_FILE` exclusively to `<skill-path>/SKILL.md`, and every implemented security check reads only that file. It does not inspect shell scripts, Python files, JavaScript files, binaries, configuration files, or other executable resources within the target Skill. This is a fail-open design for a security scanner. A Skill can keep its documentation benign while placing credential access, remote communication, destructive commands, obfuscated payloads, or persistence logic in `scripts/` or another auxiliary directory. The scanner will not observe those behaviors. The project documentation claims detection of network exfiltration, credential harvesting, destructive operations, and obfuscation, but those guarantees cannot apply to code outside `SKILL.md`. ### Attack Path 1. An attacker creates a Skill with valid metadata and ordinary documentation in `SKILL.md`. 2. The attacker places malicious behavior in an auxiliary file such as `scripts/run.sh`. 3. The Skill inst ...[truncated 884 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Recursively enumerate and inspect all relevant files under the target Skill directory, including shell, Python, JavaScript, TypeScript, PowerShell, configuration, and executable files. 2. Use an explicit file-type policy and report every skipped or unsupported file so incomplete coverage cannot silently produce a safe verdict. 3. Detect binaries separately and mark unreviewed executable content as requiring manual analysis. 4. Canonicalize every path and reject symbolic links or resolved paths that escape the selected Skill directory. 5. Apply file-count and file-size limits to prevent resource-exhaustion attacks. 6. Add language-aware checks for network access, credential-file access, command execution, persistence, obfuscation, and destructive operations. 7. Cap the trust score or return an inconclusive result whenever executable content could not be analyzed. 8. Add regression tests containing a benign `SKILL.md` and malicious helper scripts in multiple subdirectories. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/scan-skill.sh:32
Finding
Global allowlist check suppresses unrelated malicious network calls<![CDATA[ ## Vulnerability Details **File Location**: `scripts/scan-skill.sh:32-38` **Vulnerability Type**: Network-call detection bypass **Risk Level**: High ### Vulnerable Code ```bash # Network exfiltration - look for actual calls, not examples if grep -qE "^\s*(curl|wget|fetch|axios).*https?://" "$SKILL_FILE" 2>/dev/null; then if ! grep -qE "api\.(github|openclaw)" "$SKILL_FILE" 2>/dev/null; then ISSUES+=("[MEDIUM] Makes network calls to external domains") fi fi ``` ### Technical Analysis The first search detects whether any candidate network call exists. The second search then checks the entire `SKILL.md` for either `api.github` or `api.openclaw`. These two searches are not correlated. If an allowlisted string appears anywhere in the file, the scanner suppresses the warning for every detected network call, including calls to unrelated attacker-controlled domains. The expression also performs substring matching rather than parsed hostname validation. Consequently, strings such as an attacker-controlled hostname containing an allowlisted fragment may satisfy the check even when the destination is not operated by GitHub or OpenClaw. The detector is additionally limited to a small set of command names appearing at the beginning of a line, allowing other clients, wrappers, variable-based URLs, or differently structured commands to evade detection. ### Attack Path 1. An attacker adds a network request that transmits data to an attacker-controlled endpoint. 2. The attacker places `api.github` or `api.openclaw` elsewhere in `SKILL.md`, such as in descriptive text, a comment, or an unrelated legitimate URL. 3. The first `grep` detects that a network call exists. 4. The second `grep` finds the unrelated allowlisted string anywhere in the document. 5. Because the inner condition becomes false, no network issue is added. 6. Documentation-related score bonuses can then cause the Skill to receive a favorable result. 7. If the user later invokes t ...[truncated 645 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Extract every candidate URL and evaluate each destination independently. 2. Parse URLs with a proper URL parser rather than using document-wide substring searches. 3. Compare normalized hostnames against exact approved hosts or boundary-safe subdomain rules. 4. Do not suppress findings merely because an unrelated allowlisted URL appears elsewhere in the file. 5. Distinguish between network access and possible exfiltration; report all destinations and separately assess methods, transmitted inputs, headers, and request bodies. 6. Detect additional network clients and language APIs, including indirect invocation and variable-based destinations. 7. Treat malformed, dynamic, shortened, or unparseable destinations as requiring manual review. 8. Add bypass tests covering mixed legitimate and malicious URLs, comments containing allowlisted strings, deceptive subdomains, and multiple network calls. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/scan-skill.sh:51
Finding
Manipulable trust score can produce unsupported safe-use recommendations<![CDATA[ ## Vulnerability Details **File Location**: `scripts/scan-skill.sh:51-62, 84-88, 122-130` **Vulnerability Type**: Unsafe trust scoring and provenance spoofing **Risk Level**: High ### Vulnerable Code ```bash # Check metadata if grep -qE "(name:|description:)" "$SKILL_FILE" 2>/dev/null; then GREEN_FLAGS+=("Has proper metadata") fi # Check for documentation if grep -qE "^## " "$SKILL_FILE" 2>/dev/null; then GREEN_FLAGS+=("Well documented") fi # Calculate trust score SCORE=70 # Base score ``` ```bash # Check for official skills if [[ "$SKILL_PATH" == *"openclaw/skills"* ]] || [[ "$SKILL_PATH" == *"/openclaw/skills/"* ]]; then SCORE=$((SCORE + 20)) GREEN_FLAGS+=("Official OpenClaw skill") fi ``` ```bash # Recommendation echo "💡 Recommendation:" if [ $SCORE -ge 80 ]; then echo " Safe to use - well documented, standard permissions" elif [ $SCORE -ge 60 ]; then echo " Review before use, monitor usage" elif [ $SCORE -ge 40 ]; then echo " Use with caution in sandbox" else echo " Review carefully - multiple risk factors" fi ``` ### Technical Analysis The default score is 70. Merely containing a matching metadata string and a level-two Markdown heading creates two green flags, adding ten points and reaching the threshold for the explicit `Safe to use` recommendation. Neither property demonstrates that executable behavior is safe. Both are fully controlled by the author of the scanned Skill. The scanner also infers official OpenClaw provenance solely from a substring in the local path. A local directory name is not authenticated provenance and can be selected or influenced by an attacker. Matching the path adds 20 points and presents the Skill as official. The confidence implied by the score is further unsupported because several detection capabilities advertised by the project—such as credential harvesting, destructive operations, and obfuscated command detection—are not implemented in the script. A high score ...[truncated 1400 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the unconditional high base score with an evidence-based model in which unverified behavior remains unknown rather than presumed safe. 2. Do not award security points merely for metadata or documentation formatting. 3. Authenticate provenance through signed packages, verified registry metadata, cryptographic digests, or another trusted source. Never infer official status from a filesystem path. 4. Prevent incomplete scan coverage from producing a safe verdict. 5. Implement all detection capabilities claimed in the documentation or revise the documentation to state the actual limitations. 6. Change categorical language such as `Safe to use` to a bounded statement describing what was analyzed and what remains unverified. 7. Include scan coverage, skipped files, unsupported languages, dynamic destinations, and unresolved findings in the final output. 8. Require manual review or sandboxed execution when executable content or security-relevant behavior cannot be conclusively assessed. 9. Add adversarial scoring tests demonstrating that metadata, headings, and attacker-selected paths cannot independently generate a low-risk classification. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (8)

Self-Modification

High
Category
Rogue Agent
Content
clawhub install skill-security-scanner

# Update
clawhub update skill-security-scanner
```

### Option 2: Manual
Confidence
85% confidence
Finding
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Credential Access

High
Category
Privilege Escalation
Content
2. **Credential harvesting**
   ```bash
   # Example: reading credentials
   # cat ~/.aws/credentials
   # grep "password" /etc/shadow
   ```
Confidence
90% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
```bash
   # Example: reading credentials
   # cat ~/.aws/credentials
   # grep "password" /etc/shadow
   ```

3. **Persistence mechanisms**
Confidence
95% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
3. **Persistence mechanisms**
   ```bash
   # Example: auto-start, cron, systemd
   # sudo crontab -l
   # systemctl enable
   ```
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Session Persistence

Medium
Category
Rogue Agent
Content
3. **Persistence mechanisms**
   ```bash
   # Example: auto-start, cron, systemd
   # sudo crontab -l
   # systemctl enable
   ```
Confidence
85% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
```bash
   # Example: auto-start, cron, systemd
   # sudo crontab -l
   # systemctl enable
   ```

4. **Obfuscated code**
Confidence
80% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The script markets itself as a security scanner but derives trust primarily from weak heuristics such as documentation presence, metadata formatting, and especially repository path matching for 'official' skills. This can create a false sense of safety and allow a malicious or unsafe skill to receive an inflated score despite dangerous behavior not being detected by the simplistic checks.

Missing User Warnings

Low
Confidence
80% confidence
Finding
This shell script inspects the target skill's SKILL.md contents and specifically checks for patterns like KEY, TOKEN, SECRET, and PASSWORD. While the behavior is central to scanning, the script does not disclose to the user that it will parse file contents for potentially sensitive metadata beyond the generic 'Scanning' message.

Static analysis

No suspicious patterns detected.