Back to skill

Security audit

Apache Echarts

Security checks for vulnerabilities and agentic risk

Overview

This charting skill is mostly coherent, but its HTML template can embed untrusted chart content into executable browser code.

Review generated HTML before opening or sharing it, especially when the chart data or title came from an untrusted source. Prefer a version that safely serializes chart options and escapes titles, and be aware that opened charts load ECharts from jsDelivr.

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/template.html:6
Finding
Unescaped Template Substitution Enables HTML and JavaScript Injection<![CDATA[ ## Vulnerability Details **File Location**: `assets/template.html`, lines 6-34 **Vulnerability Type**: HTML and JavaScript injection through unsafe template interpolation **Risk Level**: High ### Vulnerable Code ```html <title>{{TITLE}}</title> ``` ```html <div class="chart-title">{{TITLE}}</div> ``` ```html <script> var userOption = {{OPTION}}; ``` ### Technical Analysis The template directly interpolates `{{TITLE}}` into HTML title and body contexts and inserts `{{OPTION}}` into an executable JavaScript context. No context-aware escaping, validation, or safe serialization is required by the template or its accompanying instructions. An attacker-controlled title can terminate the surrounding HTML element and introduce arbitrary markup or executable script. For example, a title containing `</title><script>/* attacker code */</script><title>` breaks out of the title element and adds a script to the generated page. The `{{OPTION}}` placeholder presents an additional JavaScript injection path. If option content is inserted as raw text rather than generated through a trusted JSON serializer, an attacker can terminate the expected object expression and append arbitrary JavaScript. Values containing `</script>` can also terminate the surrounding script element because HTML parsing recognizes the closing tag even when it appears inside a JavaScript string. The generated artifact is intended to be saved as an HTML file and opened in a browser, making this a persistent client-side injection vulnerability rather than a transient rendering defect. ### Attack Path 1. An attacker supplies crafted chart input through a title, series label, option value, or other content that reaches `{{TITLE}}` or `{{OPTION}}`. 2. The chart-generation workflow substitutes the attacker-controlled value directly into `assets/template.html`. 3. The resulting HTML file contains attacker-provided markup or JavaScript outside the intended data context. 4. A user opens the ge ...[truncated 1254 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Do not interpolate titles as raw HTML.** Keep the relevant elements empty and assign their content with `textContent`: ```html <title>Chart</title> <div class="chart-title" id="chart-title"></div> ``` ```js document.title = safeTitle; document.getElementById('chart-title').textContent = safeTitle; ``` 2. **Serialize chart options with a trusted JSON serializer.** Generate `{{OPTION}}` using `JSON.stringify` or an equivalent serializer rather than concatenating user-provided JavaScript source. 3. **Escape script-closing sequences.** When embedding serialized JSON inside a script element, encode at least `<`, `>`, `&`, U+2028, and U+2029. In particular, prevent attacker input from producing a literal `</script>` sequence. A safer design is to place serialized data in a non-executable element: ```html <script id="chart-option" type="application/json">SAFE_SERIALIZED_JSON</script> ``` Then parse it: ```js var userOption = JSON.parse( document.getElementById('chart-option').textContent ); ``` The JSON embedded in this element must still be encoded so user input cannot terminate the script element. 4. **Restrict options to data-only JSON.** Reject functions, executable expressions, event-handler attributes, raw HTML fragments, and unexpected object properties unless a documented feature explicitly requires them. 5. **Apply context-specific encoding.** Use HTML text encoding for HTML contexts, attribute encoding for attributes, URL validation for URLs, and JSON encoding for data consumed by JavaScript. A single generic escaping function is not sufficient for all contexts. 6. **Add a restrictive Content Security Policy where deployment permits it.** Move inline JavaScript into a local static file or protect it with a nonce or hash, and restrict `script-src` and `connect-src` to necessary origins. CSP should be treated as defense in depth rather than the primary fix. 7. **Add security regression tests** covering payloa ...[truncated 303 chars]
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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 (3)

Vague Triggers

Medium
Confidence
96% confidence
Finding
The trigger phrases are broad enough to match many ordinary requests such as 'draw a chart' or 'visualize data,' which can cause the skill to activate unexpectedly. In an agent environment, overbroad activation can lead to unrequested file generation, external CDN usage, or handling of data in a way the user did not explicitly intend.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The documentation advertises `window.__echarts_export__.getPngUrl(2)` and `window.__echarts_export__.resize()` as available APIs and lists `window.__echarts_export__` as part of the generated output. However, the actual HTML/JS template shown in the file only initializes the chart, sets options, handles resize, and registers a `download` listener; it never creates `window.__echarts_export__`. This is an active contradiction between stated behavior and the code example the skill instructs users to generate.

Missing User Warnings

Low
Confidence
83% confidence
Finding
The skill instructs the agent to save a complete HTML file to the workspace without explicitly requiring user awareness or confirmation. In practice, this can create files the user did not expect, and because the output is executable HTML with remote script loading, it increases the chance of unintended artifact creation and later execution.

Static analysis

No suspicious patterns detected.