Back to skill

Security audit

幼儿园英语课程体系

Security checks for vulnerabilities and agentic risk

Overview

This worksheet skill is mostly purpose-aligned, but it needs review because the generated HTML can include an unescaped child name even though the skill claims user input is escaped.

Review before installing. Keep outputs in a workspace folder, avoid entering child names or other fields containing HTML-like characters such as < or > until the generator escapes them, and confirm the request is specifically for kindergarten English before allowing it to create files.

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

Warning
Location
scripts/generate_worksheet.py:84
Finding
Stored HTML and JavaScript Injection Through the Worksheet Name Field<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_worksheet.py:84` **Vulnerability Type**: Stored HTML injection / local cross-site scripting **Risk Level**: Medium ### Vulnerable Code ```python name_html = f'<span class="fill">{name}</span>' if name else '<span class="fill">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>' ``` The value originates from the user-controlled `--name` command-line argument and is passed to `render_html()` before the resulting document is written to disk: ```python html = render_html(args.name, level, activities, args.columns, not args.no_answers, lang, args.score) ``` ### Technical Analysis The `name` value is interpolated directly into an HTML document without contextual HTML escaping. An attacker can therefore terminate the intended `<span>` content and insert arbitrary HTML, including elements with JavaScript event handlers. For example, the following value is interpreted as markup rather than displayed as a literal name: ```html <img src=x onerror="alert(document.domain)"> ``` This behavior contradicts the security statement in `SKILL.md` claiming that user input is escaped before being added to HTML. The generated document is stored locally, making this a stored injection vulnerability. The payload runs when a user opens the generated worksheet in a browser. Browser restrictions for `file://` documents limit some access, but they do not prevent arbitrary manipulation of the worksheet DOM or all outbound requests initiated by injected elements or scripts. ### Attack Path 1. An attacker persuades a user or Agent to generate a worksheet with a crafted child name. 2. The crafted value is supplied through `--name`, for example: ```text <img src=x onerror="document.body.innerHTML='Modified worksheet'"> ``` 3. `render_html()` inserts the value directly into the worksheet header. 4. The generator writes the malicious markup into the output HTML file. 5. The user opens the worksheet ...[truncated 1029 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Escape the name before inserting it into HTML: ```python import html safe_name = html.escape(name, quote=True) name_html = ( f'<span class="fill">{safe_name}</span>' if name else '<span class="fill">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>' ) ``` 2. Treat every value originating from command-line arguments, review JSON files, or future custom content as untrusted. Escape text according to its output context before including it in HTML. 3. Keep trusted generator markup separate from plain-text data. Do not permit plugins to convert user-controlled strings into trusted HTML without sanitization. 4. Add regression tests covering names containing: ```text < > & " ' </span> <script>alert(1)</script> <img src=x onerror=alert(1)> ``` Tests should verify that these values appear as literal text and do not create executable elements. 5. Add a restrictive Content Security Policy as defense in depth. Because the current print button uses an inline `onclick` handler, first move that behavior into a permitted external or nonce-protected script. The policy should disable object embedding and unauthorized network destinations. 6. Update the documented HTML-escaping security claim only after escaping is implemented and tested. ]]>
Vulnerability Patterns
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (2)

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill instructs the agent to read and write local files, generate HTML/JSON outputs, and maintain a progress journal, but no explicit permissions are declared. This creates a trust and containment gap: a host may grant broader filesystem access than users expect, and the documentation normalizes local file operations without clear scoping or enforcement.

Vague Triggers

Medium
Confidence
79% confidence
Finding
The trigger guidance includes broad natural-language phrases and at least one out-of-scope example, increasing the chance that the skill activates on unrelated requests. In an agent environment with file-generation capabilities, unintended activation can cause unauthorized local writes, creation of unnecessary artifacts, or workflow hijacking away from the user's actual intent.

Static analysis

No suspicious patterns detected.