Back to skill

Security audit

Skill Scoreboard

Security checks for vulnerabilities and agentic risk

Overview

The skill is a local usage scoreboard, but it also ships an undocumented script that reads OpenClaw gateway logs and records inferred skill usage, so users should review it before installing.

Install only if you are comfortable with a local scoreboard that persists usage and error history. Review or remove parse_gateway_logs.py before use if you do not want the skill to read gateway logs or infer activity from message text, and avoid enabling the cron example until retention, redaction, and scope are acceptable.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Findings (1)

other

Warning
Location
scripts/parse_gateway_logs.py:46
Finding

Undisclosed Inspection of Potentially Sensitive Gateway Message Content

Content
View full analysis

Vulnerability Details

File Location: scripts/parse_gateway_logs.py, lines 46-61 and 81-101
Vulnerability Type: Undisclosed sensitive gateway-log reconnaissance
Risk Level: Medium

Vulnerable Code

python
# Gateway log directory
LOG_DIR = Path("/tmp/openclaw")

def get_gateway_logs(days: int = 1) -> list:
    """Get Gateway log content."""
    logs = []
    today = date.today()

    for i in range(days):
        log_date = today - timedelta(days=i)
        log_file = LOG_DIR / f"openclaw-{log_date.isoformat()}.log"

        if log_file.exists():
            with open(log_file, 'r', encoding='utf-8') as f:
                logs.append(f.read())

    return logs
python
def parse_gateway_logs(logs: list) -> dict:
    """Parse Gateway logs and extract Skill usage."""
    skill_usage = defaultdict(lambda: {
        'count': 0,
        'total_chars': 0,
        'examples': []
    })

    for log_content in logs:
        lines = log_content.split('\n')

        for line in lines:
            if '"type":"error"' in line or '"type":"warn"' in line:
                continue

            try:
                entry = json.loads(line)
                msg = entry.get('0', '') or entry.get('message', '')

                if isinstance(msg, str):
                    skills = detect_skill_from_text(msg)
                    for skill in skills:
                        skill_usage[skill]['count'] += 1
                        skill_usage[skill]['total_chars'] += len(msg)
                        if len(skill_usage[skill]['examples']) < 3:
                            example = msg[:100].replace('\n', ' ')
                            skill_usage[skill]['examples'].append(example)
            except:
                continue

Technical Analysis

The parser reads complete OpenClaw gateway log files and examines arbitrary message bodies to infer Skill usage from keywords. This is broader than consuming structured Skill invocation events and may expo ...[truncated 2417 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace message-body keyword detection with parsing of structured, explicitly defined Skill invocation metadata.
  2. Do not read arbitrary message or 0 fields unless the user has provided explicit, informed consent.
  3. Remove the examples field and message-excerpt collection because the excerpts are unused by the recording workflow.
  4. Document parse_gateway_logs.py, the exact files it accesses, the fields it processes, retention behavior, and associated privacy implications in SKILL.md.
  5. Apply strict input controls, including maximum file sizes, maximum line lengths, accepted JSON schemas, and bounded processing windows.
  6. Process logs incrementally rather than loading complete files into memory.
  7. Restrict accepted log files to validated regular files under the intended directory and reject symbolic links where appropriate.
  8. Avoid broad exception handling; catch specific parsing and I/O exceptions and report malformed or unexpected records safely.
  9. Add a privacy-preserving mode that records only aggregate invocation counters and durations without retaining message content.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (13)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The documented behavior materially differs from the analyzed implementation: instead of only providing transparent scoreboard/reporting features, it reportedly reads Gateway logs, infers skill usage from keywords, and invokes external scripts to write scores. This hidden data collection and side-effect behavior is dangerous because users and reviewers cannot accurately assess what data is accessed, what is persisted, or what commands are executed.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill advertises and relies on shell, file read, and file write behavior but declares no explicit tool scope or permission boundary. In a high-priority skill that processes broad user requests and persists data, this increases the chance of unintended command execution, filesystem access, and privilege creep without clear operator review.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The trigger phrases include very broad natural-language prompts such as '今天情况如何' and '工作流复盘', which can match ordinary conversation and cause the skill to activate unexpectedly. Because the skill performs logging, file writes, and shell-driven reporting, accidental activation can expand data collection and execution beyond what the user intended.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill persistently stores skill usage and error data but does not clearly warn users about this logging behavior in a consent-oriented way. Persistent operational logs can contain sensitive prompts, identifiers, error traces, or behavioral metadata, making undisclosed retention a privacy and security concern.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script scans general gateway logs for a wide set of unrelated tool and skill keywords and assigns scores based on text mentions, effectively creating a broad monitoring mechanism. In this context, that is dangerous because it collects and processes cross-skill activity without clear minimization, and the heuristic matching can misattribute usage, exposing operational behavior and distorting rankings.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This script performs state-changing writes to the scoreboard by converting broad gateway log matches into scored usage records, which goes beyond passive analytics/reporting. That creates an integrity risk: unrelated or misdetected log content can inflate scores, poison historical metrics, and trigger downstream automation such as daily reports or workflow solidification based on inaccurate data.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/parse_gateway_logs.py (reported line 126)May include surrounding context.

python
'--success', 'true'
    ]
    
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode == 0:
        print(f"  ✅ {skill}: 记录 {count} 次, ~{duration:.1f}s")
    else:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script persistently stores detailed usage history and raw error messages in user-home files without consent, redaction, retention controls, or access hardening. Error messages can contain secrets, internal paths, prompts, tokens, or sensitive operational context, so long-lived local logs increase privacy and credential-exposure risk if the host or account is shared or later compromised.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The cron example hard-codes the timezone to "Asia/Shanghai", which imposes a locale-specific behavior without offering a choice or stating that it is only an example. Under the language/locale policy, fixed locale settings should be opt-in or clearly documented as user-selectable.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The top-level docstring is entirely in Chinese and presents the skill as such without offering any language or locale choice. This can violate a language/locale policy when users are not explicitly opting into Chinese-only behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

Natural-language strings throughout the file, including the module description, CLI help text, and console output, are exclusively in Chinese. This imposes a fixed language/locale on users without any documented opt-in or alternative language support.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The calculate_complexity docstring states the normalized result is scaled into the interval [0.95, 1.05]. However, the implemented normalization in get_all_skills uses 0.95 + normalized * 0.0475, producing weights only in [0.95, 0.9975], which actively contradicts the documented behavior.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The manifest focuses on tracking skill calls, scores, leaderboards, logs, snapshots, and workflow reviews. This code additionally enumerates every directory under ~/SharedSkills and reads .md/.js/.py/.sh/.json files from each skill to derive weights, which is a broader repository-inspection behavior not clearly disclosed as an implementation detail of querying or reporting usage.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.