Back to skill

Security audit

AI Question Generator

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly does what it says, but its generated HTML can run injected JavaScript from quiz content, so users should review it before installing.

Install only if you trust the quiz source material or can inspect the generated HTML before opening it. Prefer passing quiz JSON through stdin or a file rather than inline shell arguments, and keep output paths inside the current workspace.

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/generate_quiz.py:500
Finding

Arbitrary JavaScript Execution Through Unsafe Quiz Data Embedding

Content
View full analysis
const quizData = {json.dumps(data, ensure_ascii=False)}; let answered = {{}}; ``` Additional unescaped HTML and attribute sinks include: ```python ``` ```python
``` ```python html_parts.append(f'{i+1}') ``` ```python html += f'{t} ×{count}' html += f'{b} ×{count}' html += f'{kp} ×{count}' ``` ```python sections_html += f'

{qtype}

共{len(group)}题,{group_score}分
' ``` ### Technical Analysis The renderer accepts quiz data from a command-line argument or standard input and writes it into a standalone HTML document. Although some visible text fields use `html.escape()`, the complete data object is serialized directly inside an executable `` sequence. A field containing a value such as: ```html ``` can terminate the original script element and introduce a new executable script. Other fields, including question IDs, types, difficulty labels, Bloom labels, and knowledge-point labels, are interpolated into HTML ...[truncated 2210 chars]
Remediation
View remediation
... ``` Before embedding, encode at least `<`, `>`, `&`, U+2028, and U+2029. For example: ```python serialized = json.dumps(data, ensure_ascii=False) serialized = ( serialized .replace("&", "\\u0026") .replace("<", "\\u003c") .replace(">", "\\u003e") .replace("\u2028", "\\u2028") .replace("\u2029", "\\u2029") ) ``` Then parse the element's text content: ```javascript const quizData = JSON.parse( document.getElementById('quiz-data').textContent ); ``` 3. Remove inline handlers such as `onchange="checkAnswer(...)"`. Bind events with `addEventListener()` from static JavaScript. 4. Validate question IDs with a strict allowlist, such as `^[A-Za-z0-9_-]{1,64}$`. 5. Restrict question type, difficulty, and Bloom level to known enumerated values. 6. Apply context-specific encoding: - HTML text encoding for text nodes. - HTML attribute encoding for attribute values. - Safe DOM APIs for element construction. - JavaScript serialization only for JavaScript values. 7. Prefer constructing dynamic elements with `document.createElement()`, `textContent`, and `setAttribute()` rather than concatenating HTML strings. 8. Add regression tests using payloads containing quotes, angle brackets, ``, inline-event syntax, and malformed identifiers. 9. Consider a restrictive Content Security Policy that disallows inline scripts and limits network destinations as a defense-in-depth control. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:127
Finding

Shell Command Injection Risk in Documented JSON Invocation

Content
View full analysis
' --output quiz.html ``` ### Technical Analysis The documented command instructs the Agent to place complete JSON data inside a single-quoted shell argument. Quiz JSON can contain user-derived material, question text, titles, answers, and explanations. A single quote inside that data terminates the shell's quoted argument. If the command is assembled as text and executed through a shell, subsequent attacker-controlled characters can be interpreted as shell syntax rather than JSON data. For example, a malicious value could contain an apostrophe followed by command separators and an operating-system command. JSON encoding does not protect data from shell parsing because JSON escaping and shell escaping are different security contexts. Exploitation depends on the Agent or integration interpolating dynamic JSON into the documented command and executing it through a shell. The Python script itself does not invoke a shell, but the recommended invocation pattern creates the unsafe execution boundary. ### Attack Path 1. An attacker submits source material containing an apostrophe and shell metacharacters. 2. The generated quiz preserves the malicious value in its JSON representation. 3. The Agent follows the documented command and substitutes the complete JSON object for the quoted placeholder. 4. The command is passed to a shell as a single command string. 5. The attacker-controlled apostrophe closes the intended `--data` argument. 6. Shell separators cause the remaining attacker-controlled text to be interpreted as a command. 7. The injected command executes with the permissions of the user or Agent process running the Skill. ### Impact Assessment Successful exploitation can provid ...[truncated 670 chars]
Remediation
View remediation
'` example from the primary documentation, or clearly limit it to trusted, static examples. 4. Never construct a shell command by concatenating or formatting user-controlled data. 5. If temporary files are used, create them with secure APIs, restrictive permissions, unpredictable names, and reliable cleanup. 6. Add tests containing apostrophes, semicolons, command substitutions, newlines, and other shell metacharacters to ensure they remain inert data. ]]>
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

该代码块的核心用途是“Quiz JSON -> interactive HTML renderer”。它从命令行参数或stdin读取JSON,按题型分组,生成题目页面、答题卡、统计区块,并通过前端JavaScript实现客观题判分、显示答案、打印和重置。虽然输出形式与声明中的“交互式HTML试卷”部分一致,也支持多种题型的呈现,并显示答案/解析/Bloom层次/难度等字段,但这些字段都依赖外部输入数据,代码没有任何AI生成、知识点理解、材料解析、题目构造或Bloom标注推断能力。因此,声明把该技能描述为“AI智能出题系统”明显高于实际行为;实际更像是“试卷HTML渲染器/展示器”。这是主要目的上的实质性不一致。

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill instructs the agent to write an output file via a Python script, but it does not declare any explicit tool scope such as permissions or allowed-tools. That mismatch can lead to unexpected file-write capability being exercised without clear sandboxing or user visibility, increasing the risk of unauthorized file creation or overwrite if the skill is invoked in a permissive runtime.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger list contains very broad, everyday phrases, which increases the chance of accidental or context-inappropriate invocation. In an agent environment, overbroad triggers can cause the skill to activate on unrelated conversations and then perform file generation or other actions unexpectedly, expanding the attack surface for prompt-routing abuse.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest description is written as a Chinese-only system description and presents the skill as an "AI智能出题系统" without indicating that users may choose output language or locale. This can violate language/locale policy because the skill appears to assume a fixed language rather than offering opt-in or documenting a justified regional constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

SQP-3 applies to all file types and covers language or locale policy violations. This markdown guidance forces a specific language for readers and users of the skill content, but the file does not provide an opt-in, alternative language, or justification that it is intended only for a Chinese-language context.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code sets the document language to zh-CN and renders core interface labels, controls, alerts, and placeholders exclusively in Chinese. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

This markdown file presents all instructions in Chinese and does not mention whether the user can choose another language or locale. Under the policy rule for natural-language violations, forcing a specific language without opt-in can be a policy issue when no justification or choice is documented.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

This markdown file contains instructional content that implicitly enforces a single language/locale for skill use. Under the policy, forcing a specific language without offering user choice or documenting the locale constraint can be a natural-language policy violation.

Content

No source excerpt is available for this finding.