Back to skill

Security audit

Token Monitor

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its token-reporting purpose, but it reads sensitive local session history and has a confirmed unsafe HTML report path that can render unescaped session-derived content.

Install only if you are comfortable giving the skill access to local OpenClaw session logs. Treat generated reports as sensitive, avoid running it on untrusted JSONL files, and prefer JSON or Markdown output until the HTML escaping issue is fixed.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/analyze_session.py:221
Finding

Stored HTML Injection Through Unescaped Skill Names

Content
View full analysis

Vulnerability Details

File Location: scripts/analyze_session.py:221-223, 577-603
Vulnerability Type: Stored HTML injection caused by unsafe output encoding
Risk Level: High

Vulnerable Code

Skill names are read from untrusted JSONL tool-call arguments:

python
skill_name = args.get("skill") or args.get("name")
if skill_name and self.is_valid_skill_name(skill_name):
    return skill_name.lower()

The resulting value is inserted directly into two HTML contexts:

python
for skill_name, data in results["skills"].items():
    rate_class = 'high' if data['成功率'] >= 90 else 'medium' if data['成功率'] >= 70 else 'low'

    html += f"""
        <tr>
            <td><strong>{skill_name}</strong></td>
            <td>{data['调用次数']:,}</td>
            <td>{data['输入tokens']:,}</td>
            <td>{data['输出tokens']:,}</td>
            <td>{data['缓存读取tokens']:,}</td>
            <td><strong>{data['总tokens']:,}</strong></td>
            <td>{data['缓存命中率']:.1f}%</td>
            <td class="success-rate {rate_class}">{data['成功率']:.0f}%</td>
        </tr>
"""

html += """
    </tbody>
</table>

<h2>📋 详细分析</h2>
"""

for skill_name, data in results["skills"].items():
    html += f"""
<div class="skill-detail">
    <h3>{skill_name}</h3>

Technical Analysis

Session JSONL files are input data and therefore cannot be trusted. A skill name may be obtained from the skill or name property of a Skill tool call. Although is_valid_skill_name() performs format-oriented checks, those checks do not provide contextual HTML sanitization or encoding. In particular, accepted values are not constrained to a safe alphanumeric grammar and can contain HTML metacharacters if they otherwise meet the validation rules.

to_html() subsequently interpolates the skill name into table-cell and heading content without HTML escaping. An attacker-controlled value can therefore terminate th ...[truncated 1495 chars]

Remediation
View remediation

Remediation Suggestions

  1. Escape every dynamic text value before inserting it into HTML:

    python
    from html import escape
    
    safe_skill_name = escape(str(skill_name), quote=True)
    

    Use safe_skill_name in both the table cell and heading.

  2. Prefer an HTML templating engine with automatic escaping enabled rather than constructing the document through formatted string concatenation.

  3. Enforce a strict skill-name grammar at the trust boundary, for example:

    python
    re.fullmatch(r"[A-Za-z][A-Za-z0-9_-]*", name)
    

    Strict validation is defense in depth and must not replace context-appropriate output encoding.

  4. Apply HTML escaping consistently to all future values originating from session files, including tool names and any additional metadata added to reports.

  5. Add regression tests containing payloads with tags, event handlers, quotes, ampersands, and angle brackets. Verify that generated reports contain encoded text such as &lt; and do not create executable DOM elements.

  6. Consider applying a restrictive Content Security Policy to generated reports, such as disallowing scripts, as an additional mitigation.

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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (8)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill invokes a Python script that reads session files and can write output reports, but it declares no explicit tool scope or permissions boundaries. Without an allowlist, an agent may use broader file read/write capabilities than the user expects, increasing the risk of unintended access to sensitive session data or arbitrary file creation.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger keywords include broad terms like "token", "会话分析", and "使用报告", which can overlap with ordinary conversation and cause unintended activation. Mis-triggering a skill that reads local session JSONL files can expose private project history or generate files when the user did not mean to invoke this capability.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill instructions describe reading ~/.claude/projects/... session files and optionally writing HTML reports, but they do not clearly warn the user that local conversation history will be accessed and output files may be created. This weakens informed consent around potentially sensitive data processing, especially because session logs may contain prompts, tool outputs, and other confidential context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The documentation explicitly reveals the default session storage path and shows example session contents that include assistant thinking fields, tool calls, timestamps, and token usage. In the context of a skill designed to analyze session JSONL files, this increases the chance that operators will access or process highly sensitive conversation artifacts without adequate warnings, minimization, or redaction, potentially exposing secrets, private prompts, or internal reasoning traces.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Natural-language strings throughout the file, including the module docstring and CLI argument descriptions, are presented only in Chinese with no option to select another language. This creates a locale/language policy concern because the skill imposes a specific language on users rather than offering choice or documenting a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest describes a tool for analyzing OpenClaw session JSONL files and producing token/performance reports. However, _load_known_skills inspects ~/.claude/skills to discover locally installed skills, which expands the data sources beyond the target session files and reveals local environment information not necessary for basic token monitoring.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The HTML report embeds user-derived values such as skill names and tool names directly into HTML without escaping. If a session contains attacker-controlled strings like HTML or script payloads, opening the generated report in a browser could trigger stored XSS or markup injection, exposing local data in the browser context or misleading the analyst viewing the report.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

整个技能说明均以中文撰写,且未说明是否支持其他语言或允许用户按偏好选择输出语言。按规则,若技能在语言或地区上施加单一约束而无用户选择或合理说明,属于自然语言策略风险。

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.