Back to skill

Security audit

skill-security-scanner-clean

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent security-scanner skill, but it needs review because its install guard handles untrusted archives unsafely and its scan results can overstate how complete the review was.

Review before installing. Run it only on skill copies in a disposable directory, avoid elevated privileges, do not treat a PASS result as proof a skill is safe, manually inspect unsupported files, and be careful scanning .skill archives until archive limits and temporary-directory cleanup are added.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/security_scanner.py:190
Finding
Security scanner omits instruction-bearing and unsupported file types from dangerous-pattern analysis<![CDATA[ ## Vulnerability Details **File Location**: `scripts/security_scanner.py:190-205` and `scripts/security_scanner.py:320-350` **Vulnerability Type**: Incomplete security-analysis coverage **Risk Level**: High ### Complete Code Snippet ```python # Scan all code files for ext in ['.py', '.js', '.ts', '.sh', '.bash', '.ps1']: for file_path in skill_path.rglob(f'*{ext}'): if self._should_scan_file(file_path): self._scan_file(file_path) # Scan SKILL.md skill_md = skill_path / 'SKILL.md' if skill_md.exists(): self._scan_skill_metadata(skill_md) # Scan dependency files for dep_file in ['package.json', 'requirements.txt', 'Pipfile', 'pyproject.toml']: dep_path = skill_path / dep_file if dep_path.exists(): self._scan_dependencies(dep_path) ``` The separate metadata scanner does not apply the dangerous-pattern rules: ```python def _scan_skill_metadata(self, skill_md_path: Path): """Scan SKILL.md metadata""" try: with open(skill_md_path, 'r', encoding='utf-8') as f: content = f.read() except Exception: return # Check whether enough documentation is provided if len(content) < 500: self.findings.append(SecurityFinding( rule_id="DOC001", rule_name="Documentation too short", description="SKILL.md has insufficient content and may lack adequate functionality documentation", risk_level=RiskLevel.LOW, file_path="SKILL.md", line_number=0, code_snippet="", recommendation="Provide detailed Skill functionality and usage documentation" )) # Check whether network requirements are described has_network_pattern = r'\b(network|http|request|api|url|endpoint|server)\b' if re.search(has_network_pattern, content, re.IGNORECASE): security_pattern = r'\b(security|privacy|data|sensitive|credential)\b' if not re.search(security_pattern, content, re.IGNO ...[truncated 3150 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Enumerate every archive entry and project file rather than using a small executable-extension allowlist as the complete scan boundary. 2. Apply relevant dangerous-pattern and instruction-hijacking checks to `SKILL.md` and all recursively discovered Markdown files. 3. Inspect HTML and SVG files for scripts, event handlers, external-resource references, embedded data, and active content. 4. Analyze configuration formats such as JSON, YAML, TOML, XML, and workflow definitions for commands, hooks, external URLs, and unsafe installation behavior. 5. Treat unknown extensions, extensionless files, unreadable files, and unsupported binary formats as explicit coverage warnings. 6. Report both the number of files discovered and the number fully analyzed so users can identify incomplete coverage. 7. Prevent a `PASS` verdict when security-relevant files were skipped or could not be read. 8. Add tests containing malicious patterns in root Markdown, nested Markdown, HTML, SVG, extensionless scripts, and uncommon executable formats. 9. Clearly document that static pattern matching cannot establish that a Skill is safe and avoid presenting `PASS` as an installation safety guarantee. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/install_guard.py:55
Finding
Unbounded extraction of untrusted Skill archives permits resource exhaustion<![CDATA[ ## Vulnerability Details **File Location**: `scripts/install_guard.py:55-63` **Vulnerability Type**: Unbounded archive extraction and temporary-file leakage **Risk Level**: Medium ### Complete Code Snippet ```python # Handle .skill files (zip archives) skill_path = args.skill_path if skill_path.endswith('.skill'): import tempfile import zipfile extract_dir = tempfile.mkdtemp(prefix="skill_scan_") with zipfile.ZipFile(skill_path, 'r') as z: z.extractall(extract_dir) skill_path = extract_dir ``` ### Technical Analysis The installation guard fully extracts an untrusted `.skill` ZIP archive before scanning it. No controls are applied to: - The number of archive entries - The total uncompressed size - Individual entry sizes - Compression ratios - Available disk space - Extraction duration - Special or unsupported entry types A highly compressed archive can consequently expand into a much larger amount of data. An archive containing a very large number of small files can also consume filesystem inodes and cause excessive scanner work. The directory is created with `tempfile.mkdtemp()` but is not removed after scanning, rejection, an exception, or normal completion. Repeated scans therefore leave attacker-controlled extracted data in the system temporary directory and can gradually consume storage. Modern Python ZIP handling provides protections against ordinary `../` path traversal during `extractall`; therefore, path traversal is not asserted as a confirmed issue here. The confirmed weakness is unbounded extraction and missing cleanup. ### Attack Path 1. An attacker supplies a `.skill` file containing a ZIP bomb, oversized entries, or a very large number of compressed files. 2. A user runs `install_guard.py` against the archive. 3. The guard calls `extractall()` before any security verdict is produced. 4. The archive expands until it consumes significant disk space, inodes, CPU time, or scanner resources. 5. The host ...[truncated 996 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace `tempfile.mkdtemp()` with `tempfile.TemporaryDirectory()` used as a context manager so cleanup occurs on success, rejection, and exceptions. 2. Inspect every `ZipInfo` entry before extraction. 3. Enforce conservative limits for: - Maximum entry count - Maximum size of one uncompressed entry - Maximum cumulative uncompressed size - Maximum compression ratio - Maximum nested archive depth, if nested archives are supported 4. Reject encrypted entries, special file types, unsupported compression methods, and suspicious filenames. 5. Extract entries incrementally instead of calling `extractall()`, checking cumulative limits before writing each file. 6. Verify each resolved destination remains inside the temporary extraction root. 7. Check available storage before and during extraction, and abort safely when configured limits are approached. 8. Apply execution time and memory limits when the guard is used by an automated service. 9. Ensure partial output is deleted after malformed archives, interrupted scans, and all exception paths. 10. Add regression tests using high-compression archives, oversized entries, excessive entry counts, malformed metadata, and repeated rejected scans. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (8)

Self-Modification

High
Category
Rogue Agent
Content
- **Zero-day vulnerabilities**: Unknown attack patterns
- **Logic bombs**: Time/delayed triggers
- **Polymorphic code**: Self-modifying malware
- **External payloads**: Code downloaded at runtime
- **Social engineering**: Tricking users into actions
Confidence
90% 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.

YARA rule 'keylogger_indicators': Keylogger functionality in scripts or source code [malware]

High
Category
YARA Match
Content
u[0-9a-fA-F]{4}){10,}|base64\.(b64decode|decodestring)',
            "description": "检测到可能的代码混淆,隐藏真实意图",
            "risk": RiskLevel.HIGH,
            "recommendation": "避免使用混淆代码,保持代码可读性和可审计性"
        },
        "SUSPICIOUS001": {
            "name": "键盘记录特征",
            "pattern": r'\b(keyboard|pynput|hook|GetAsyncKeyState|keylogger)',
            "description": "可能包含键盘记录功能",
            "risk": RiskLevel.CRITICAL,
            "recommendation": "OpenClaw技能不应包含键盘记录功能,这是明确禁止的行为"
        },
        "SUSPICIOUS002": {
            "name": "屏幕捕获特征",
            "pattern": r'\b(pyautogui\.screenshot|PIL\.ImageGrab|mss|screenshot|grab\s*\()',
            "description": "可能包含屏幕截图/录制功能",
            "risk": RiskLevel.HIGH,
            "recommendation": "屏幕捕获涉及隐私,必须在SKILL.md中明确�
Confidence
70% confidence
Finding
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

YARA rule 'keylogger_indicators': Keylogger functionality in scripts or source code [malware]

High
Category
YARA Match
Content
u[0-9a-fA-F]{4}){10,}|base64\.(b64decode|decodestring)',
            "description": "检测到可能的代码混淆,隐藏真实意图",
            "risk": RiskLevel.HIGH,
            "recommendation": "避免使用混淆代码,保持代码可读性和可审计性"
        },
        "SUSPICIOUS001": {
            "name": "键盘记录特征",
            "pattern": r'\b(keyboard|pynput|hook|GetAsyncKeyState|keylogger)',
            "description": "可能包含键盘记录功能",
            "risk": RiskLevel.CRITICAL,
            "recommendation": "OpenClaw技能不应包含键盘记录功能,这是明确禁止的行为"
        },
        "SUSPICIOUS002": {
            "name": "屏幕捕获特征",
            "pattern": r'\b(pyautogui\.screenshot|PIL\.ImageGrab|mss|screenshot|grab\s*\()',
            "description": "可能包含屏幕截图/录制功能",
            "risk": RiskLevel.HIGH,
            "recommendation": "屏幕捕获涉及隐私,必须在SKILL.md中明确�
Confidence
70% confidence
Finding
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill documentation demonstrates and encourages capabilities that invoke shell execution, read/write files, and process JSON output from a subprocess, but the manifest declares no explicit tool scope such as permissions or allowed-tools. This creates a trust and containment gap: consumers may install or run the skill without clear authorization boundaries, increasing the chance that powerful operations are available implicitly or reviewed inadequately.

Unrestricted Tool Access

Medium
Category
Excessive Agency
Content
| EXEC001 | Code Execution Functions | `\b(eval\|exec\|compile\|__import__\|execfile)\s*\(` | Critical |
| EXEC002 | System Command Execution | `\b(os\.system\|subprocess\.(call\|run\|Popen\|check_output)\|popen\|spawn\|shell=True)\s*\(` | High |

**Why it matters**: These functions can execute arbitrary code, bypassing normal security controls.

**Common legitimate uses**:
- Running external tools (ffmpeg, git, etc.)
Confidence
80% confidence
Finding
Skill grants unrestricted tool access without appropriate constraints. An agent with unfettered tool access can perform arbitrary actions including file modification, network requests, and code execution.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
| FILE001 | File Deletion | `\b(os\.remove\|os\.rmdir\|shutil\.rmtree\|os\.unlink)` | Medium |
| FILE002 | File Writing | `\b(open\s*\(\s*[^,\)]*,\s*['"]w\|fs\.writeFile)` | Low |

**Why it matters**: File operations can destroy data, plant malware, or modify system files.

**Common legitimate uses**:
- Creating output files
Confidence
60% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
if strict:
        cmd.append("--strict")
    
    result = subprocess.run(cmd, capture_output=True, text=True)
    
    try:
        return json.loads(result.stdout)
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
This code embeds user-facing and maintenance-relevant comments in Chinese (for example the RiskLevel descriptions) within an otherwise English-language file. That imposes a locale choice on readers and maintainers without offering an alternative or documenting that the tool is intended for a Chinese-only audience.

Static analysis

No suspicious patterns detected.