Back to skill

Security audit

Smart-Classroom Teaching

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent classroom-teaching tool, but its optional local workbench exposes unsafe state import and rendering paths that could leak or alter classroom content.

Review before installing. Use the local server only in a trusted environment, do not leave it running while browsing untrusted sites, do not import replay JSON from untrusted sources, and avoid putting identifiable student data into exported histories or state files unless it has been minimized and desensitized. The workbench should be fixed with authentication, CORS restrictions, schema validation, and safe rendering before handling sensitive classroom data.

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
assets/smart-classroom-workbench.html:438
Finding

Unauthenticated Cross-Origin State Injection Enables Browser-Side Code Execution

Content
View full analysis

Vulnerability Details

File Location: scripts/smart-classroom-serve.py:42-56, 97-101; assets/smart-classroom-workbench.html:438-451, 480-492, 576-583
Vulnerability Type: Unauthenticated cross-origin API access and stored HTML injection
Risk Level: High

Technical Analysis

The localhost HTTP service accepts arbitrary JSON at POST /api/state without authentication, authorization, origin validation, schema validation, or request-size restrictions:

python
def do_POST(self):
    path = self.path.split("?", 1)[0]
    if path != "/api/state":
        return self._send_json(404, {"error": "not found"})
    try:
        length = int(self.headers.get("Content-Length", 0))
        body = self.rfile.read(length)
        data = json.loads(body.decode("utf-8"))
    except Exception as exc:
        return self._send_json(400, {"error": "invalid JSON: %s" % exc})
    with open(_STATE_FILE, "w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)
    return self._send_json(200, {"ok": True, "state": data})

The service explicitly permits requests from every web origin:

python
def _cors_headers(self):
    self.send_header("Access-Control-Allow-Origin", "*")
    self.send_header("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
    self.send_header("Access-Control-Allow-Headers", "Content-Type")

Although the server binds only to 127.0.0.1, a malicious website opened in the same browser can issue cross-origin requests to the loopback service. The permissive preflight response allows that website to submit an application/json request to /api/state.

The workbench automatically polls the resulting state every 1.2 seconds and commits it to the rendering history:

javascript
function poll(){
  fetch("state.json?t=" + Date.now(), {cache:"no-store"})
    .then(r => { if(!r.ok) throw 0; return r.json(); })
    .then(function(d){
      const sig = JSON.stringify(d);
      if(sig === _lastPollSig) return;
 
...[truncated 5087 chars]
Remediation
View remediation

Remediation Suggestions

  1. Authenticate state API requests

    • Generate a cryptographically random token when the local server starts.
    • Require the token in a custom request header or an authorization header for GET /api/state and POST /api/state.
    • Do not place a reusable token in a publicly readable state file.
  2. Restrict cross-origin access

    • Remove Access-Control-Allow-Origin: *.
    • If cross-origin access is genuinely required, use a narrow allowlist of expected origins.
    • Validate the Origin header and reject absent or unexpected origins for browser-facing state changes.
    • Do not enable unnecessary CORS access for state-reading endpoints.
  3. Validate the state schema

    • Require the expected object structure and primitive types.
    • Allow only known values for board.type and dialogue.r.
    • Reject unexpected properties where practical.
    • Apply strict limits to request size, field lengths, history length, and collection sizes.
    • Validate imported replay JSON using the same schema before assigning it to history.
  4. Eliminate unsafe HTML construction

    • Render topic, formulas, notes, mind-map items, transcript entries, and dialogue text with textContent.
    • Build lists, labels, and dialogue elements with document.createElement rather than string concatenation.
    • Validate role values before applying them as CSS classes.
  5. Remove arbitrary active-markup support where possible

    • Prefer structured visualization primitives or a fixed drawing schema instead of accepting arbitrary HTML.
    • For SVG, parse and allow only necessary graphical elements and safe attributes.
  6. Sanitize content when HTML or SVG support is essential

    • Use a robust allowlist sanitizer.
    • Remove scripts, inline event handlers, javascript: URLs, active embedded content, foreign objects, external resource references, and unsafe SVG elements or attributes.
    • Apply sanitization to both API-supplied ...[truncated 707 chars]
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (18)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description presents a broad AI-powered smart classroom system with multiple pedagogical and multimodal capabilities. However, the supplied code only provides infrastructure: a localhost HTTP server, static file hosting from an assets directory, and a JSON state read/write API. This could support a classroom UI, but by itself it does not implement the described instructional intelligence or analysis features. The code’s primary purpose is materially narrower and different from the declared purpose, so this is a clear description-behavior mismatch.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The render path allows board.type 'svg' or 'html' and returns content that is later assigned via innerHTML, enabling arbitrary markup injection into the DOM. If state comes from imported JSON or polled external data, an attacker can inject active content or hostile SVG/HTML payloads, leading to XSS-like script execution or UI spoofing in the host context.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill explicitly instructs the host to read reference files, write state/JSON outputs, and optionally run a local service, but it declares no corresponding tool scope or permissions boundary. This creates an authorization gap where a host or agent may grant broader filesystem access than intended, increasing the risk of unintended file reads/writes or unsafe execution paths.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger list includes broad, common words such as 备课, 演示, and 讲解, which can cause the skill to activate in unrelated contexts. Unintended invocation is dangerous here because the skill is designed to read supporting files, manage persistent teaching state, and potentially write outputs or instruct use of a local service, so accidental activation could expand context exposure or lead to unwanted actions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The document declares lang="zh-CN" and all visible UI labels and instructional text are fixed in Chinese, with no indication that users may opt into another language. Under the stated policy, hard-coding a specific language without user choice or clear justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The file defines a 'generic' scene explicitly described as supporting arbitrary non-teaching product/report content, which expands the skill beyond its declared classroom-teaching purpose. That broader rendering scope increases abuse potential because the same rendering pipeline can be used to display untrusted or misleading content not constrained by the educational context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Imported replay JSON is parsed and loaded directly into history without trust checks, warnings, or sanitization, and the imported state is later rendered into the DOM. A user opening an untrusted replay file could therefore trigger malicious markup injection, deceptive UI content, or persistent unsafe states during playback.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The page continuously polls a local HTTP state.json source and commits whatever JSON it receives into application history and rendering. This undisclosed external-input channel widens the attack surface because any local service or file-serving context that can influence state.json can drive the UI and, combined with unsafe rendering, inject malicious content.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The exemplar is entirely written as a normative template in Chinese and provides no indication that other languages are supported or that the language requirement is optional. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation unless clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The catalog explicitly defines classroom record analysis, student profiling, diagnostic report generation, and personalized instruction workflows, all of which imply processing sensitive student and teacher data. Although SC7 mentions privacy desensitization, the document does not require data minimization, consent, retention limits, access controls, or a hard privacy gate before SC3/SC4 outputs, so an implementation could analyze and expose personally identifiable educational records by default.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The boundary statement says the workbench '只显示,不承担输入、不运行模型、不回写任何文件', which conveys a no-write posture. Just a few lines later, the local service is documented as providing a write path via POST /api/state that writes teaching state and generates state.json, contradicting the earlier claim rather than merely adding implementation detail.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Exporting lesson-history JSON can preserve classroom transcripts, dialogue, teaching flow, and potentially student-related content without any explicit warning, minimization, or retention guidance. In this skill's education context, exported files may contain sensitive session data and could be shared or stored insecurely, creating privacy and compliance risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Allowing arbitrary SVG/HTML content to be injected into the rendering panel creates a clear client-side code injection surface. In a browser-based workbench, untrusted HTML/SVG can execute script-capable payloads or abuse active content, leading to XSS, UI spoofing, data exposure, or manipulation of the teaching session.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The '只读性' section states '不回写 state.json' and frames polling as one-way read-only behavior. However, earlier lines specify that POST /api/state is the intended update mechanism and that state.json is temporarily generated on push, so the documentation as a whole conflicts about whether this component stack writes state files.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The instructions require users to mark messages with the Chinese prefixes "教师:" or "学生:" to distinguish roles. This imposes a specific language/locale convention without offering an alternative or documenting why the constraint is necessary, which can conflict with language choice policy expectations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The markdown includes a natural-language example that fixes the target language to '英语' for the multilingual dialogue task. Because the file does not indicate that language selection is user-driven or optional in the example, it can be read as forcing a specific language without opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

The task '多语种情景对话' explicitly introduces multilingual dialogue practice, but the catalog does not indicate that language selection is user-chosen or opt-in. Because locale/language behavior is specified in natural language without documenting user choice, it may conflict with language preference policy expectations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The file's instructional content is presented solely in Chinese throughout, which can amount to a language-policy issue when no user opt-in or alternative language path is provided. The document does not state that the skill is intentionally limited to Chinese-language users or a specific locale.

Content

No source excerpt is available for this finding.