Back to skill

Security audit

AntV Skills

Security checks for vulnerabilities and agentic risk

Overview

This graph-code reference skill has no hidden installer, but it needs Review because several copy-paste examples can generate web pages vulnerable to script injection.

Review generated UI code before using it with graph data from APIs, uploads, databases, or other users. Replace innerHTML and tooltip string interpolation with DOM construction using textContent, or sanitize all rich HTML; also review external demo URLs and add confirmation or undo for delete actions in real apps.

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

T09 · Insecure Skill Coding Practices

Error
Location
references/plugins/g6-plugin-tooltip.md:73
Finding
DOM XSS Through Unescaped Graph Data in Tooltip Content<![CDATA[ ## Vulnerability Details **File Location**: `references/plugins/g6-plugin-tooltip.md:73-85` and `references/plugins/g6-plugin-tooltip.md:108-124` **Vulnerability Type**: Unescaped HTML interpolation leading to DOM-based cross-site scripting **Risk Level**: High ### Vulnerable Code ```javascript getContent: (event, items) => { const item = items[0]; if (!item) return ''; const { data } = item; return ` <div style="padding: 8px 12px; min-width: 120px;"> <div style="font-weight: bold; margin-bottom: 4px;">${data.name || item.id}</div> ${data.age ? `<div>年龄:${data.age}</div>` : ''} ${data.dept ? `<div>部门:${data.dept}</div>` : ''} ${data.relation ? `<div>关系:${data.relation}</div>` : ''} </div> `; }, ``` The second documented variant exposes every property of the graph data: ```javascript getContent: (event, items) => { const [item] = items; const d = item.data; return ` <div style="background:#fff;border:1px solid #eee;padding:12px;border-radius:6px;box-shadow:0 2px 8px rgba(0,0,0,.1)"> <h4 style="margin:0 0 8px">${d.name}</h4> <table style="border-collapse:collapse"> ${Object.entries(d).map(([k, v]) => ` <tr> <td style="color:#999;padding:2px 8px 2px 0">${k}</td> <td style="font-weight:500">${v}</td> </tr> `).join('')} </table> </div> `; }, ``` ### Technical Analysis The examples directly interpolate graph-record fields into strings returned by the G6 tooltip `getContent` callback. These strings are intended to be interpreted as HTML. No HTML escaping, contextual output encoding, sanitization, or trusted-data requirement is applied. Graph data commonly originates from APIs, imported files, databases, or user-generated records. Consequently, properties such as `name`, `dept`, `relation`, object keys, and object values must be treated as untrusted. An attacker-controlled value such as the following can introduce a ...[truncated 1618 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Prefer returning an `HTMLElement` and assign all dynamic values through `textContent`. - Do not construct markup by interpolating graph-record properties into template literals. - If rich HTML must be accepted, sanitize it with a maintained HTML sanitizer configured to reject scripts, event-handler attributes, dangerous URLs, and unsafe elements. - Treat graph data as untrusted unless its provenance and validation are explicitly guaranteed. - Add centralized helpers for safely creating tooltip rows rather than repeating HTML construction. - Add test cases using payloads in every rendered property, including object keys. A safer implementation is: ```javascript getContent: (event, items) => { const item = items[0]; const container = document.createElement('div'); container.style.cssText = 'padding:8px 12px;min-width:120px'; const title = document.createElement('div'); title.style.cssText = 'font-weight:bold;margin-bottom:4px'; title.textContent = String(item?.data?.name ?? item?.id ?? ''); container.appendChild(title); for (const field of ['age', 'dept', 'relation']) { const value = item?.data?.[field]; if (value === undefined || value === null) continue; const row = document.createElement('div'); row.textContent = `${field}: ${String(value)}`; container.appendChild(row); } return container; }, ``` ]]>

T09 · Insecure Skill Coding Practices

Error
Location
references/behaviors/g6-behavior-click-select.md:150
Finding
DOM XSS Through Unsafe Detail Panel innerHTML Assignment<![CDATA[ ## Vulnerability Details **File Location**: `references/behaviors/g6-behavior-click-select.md:150-161` **Vulnerability Type**: Untrusted data written directly to `innerHTML` **Risk Level**: High ### Vulnerable Code ```javascript // 监听选中事件 graph.on('node:click', (event) => { const nodeId = event.target.id; const nodeData = graph.getNodeData(nodeId); // 更新 UI 面板 document.getElementById('detail-panel').innerHTML = ` <h3>${nodeData.data.name}</h3> <p>${nodeData.data.description}</p> `; }); ``` ### Technical Analysis The click handler retrieves `name` and `description` from a graph record and directly assigns a template containing those values to an element's `innerHTML`. The browser therefore parses the values as markup. Neither field is encoded or sanitized. If graph data is supplied by an API, imported file, database, or another user, either property can inject arbitrary HTML and event-handler attributes. For example, a malicious description could contain: ```html <img src=x onerror="alert(document.domain)"> ``` Clicking the affected node causes the payload to be parsed and executed. ### Attack Path 1. An attacker obtains the ability to create or modify a graph node's `name` or `description`. 2. The attacker stores an HTML injection payload in that property. 3. The victim loads the graph and clicks the malicious node. 4. The click handler retrieves the attacker-controlled record. 5. The handler interpolates the malicious value into a template literal and assigns it to `detail-panel.innerHTML`. 6. The browser creates the injected element and executes its event handler in the application origin. ### Impact Assessment The attacker can execute JavaScript with the browser privileges of the affected application. This may enable reading page-accessible sensitive data, performing authenticated API requests, altering displayed information, or presenting deceptive UI. The impact is limited by browser-origin security boundaries, Co ...[truncated 142 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Build the detail panel using DOM methods and assign dynamic values through `textContent`. - Avoid `innerHTML` for ordinary text fields. - If rich descriptions are a required feature, sanitize them with a strict allowlist before insertion. - Validate the returned node object and expected field types before rendering. - Deploy a restrictive Content Security Policy as defense in depth, but do not use CSP as a substitute for output encoding. - Add security tests covering malicious node names and descriptions. Example: ```javascript graph.on('node:click', (event) => { const nodeData = graph.getNodeData(event.target.id); const panel = document.getElementById('detail-panel'); if (!panel) return; const heading = document.createElement('h3'); heading.textContent = String(nodeData?.data?.name ?? ''); const description = document.createElement('p'); description.textContent = String(nodeData?.data?.description ?? ''); panel.replaceChildren(heading, description); }); ``` ]]>

T09 · Insecure Skill Coding Practices

Error
Location
references/elements/nodes/g6-node-html.md:82
Finding
HTML Node Examples Permit Markup and Attribute Injection<![CDATA[ ## Vulnerability Details **File Location**: `references/elements/nodes/g6-node-html.md:82-105`, `references/elements/nodes/g6-node-html.md:126-138`, and `references/elements/nodes/g6-node-html.md:150-153` **Vulnerability Type**: DOM XSS through HTML and attribute-context interpolation **Risk Level**: High ### Vulnerable Code ```javascript innerHTML: (d) => ` <div style=" display: flex; align-items: center; padding: 8px 12px; background: #fff; border: 1px solid #e8e8e8; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.08); width: 156px; box-sizing: border-box; gap: 8px; "> <img src="${d.data.avatar}" width="36" height="36" style="border-radius: 50%; flex-shrink: 0;" /> <div> <div style="font-weight: 600; font-size: 13px; color: #333;"> ${d.data.name} </div> <div style="font-size: 11px; color: #999; margin-top: 2px;"> ${d.data.role} </div> </div> </div> `, ``` A second recommended variant repeats the unsafe text interpolation: ```javascript innerHTML: (d) => ` <div id="node-${d.id}" style=" padding: 12px 16px; background: #fff; border: 2px solid #d9d9d9; border-radius: 8px; font-size: 13px; transition: border-color 0.2s; "> <div style="font-weight: bold;">${d.data.title}</div> <div style="color: #666; margin-top: 4px;">${d.data.desc}</div> </div> `, ``` The DOM-element variant still uses `innerHTML` for graph data: ```javascript innerHTML: (d) => { const div = document.createElement('div'); div.style.cssText = 'padding:12px;background:#fff;border:1px solid #eee;border-radius:8px;'; div.innerHTML = `<div>${d.data.label}</div>`; ``` ### Technical Analysis The examples interpolate graph data into both HTML text and attribute contexts. Text-context fields such as `name`, `role`, `title`, `desc`, and `label` can inject arbitrary markup. The `avatar` value is more dangerous because it is placed ins ...[truncated 1665 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Replace all dynamic HTML-string examples with DOM construction. - Assign names, roles, labels, titles, and descriptions using `textContent`. - Assign image URLs through the `src` DOM property only after URL validation. - Permit only expected schemes such as `https:` and, where required, a controlled `data:image/...` subset. - Consider restricting image origins to an explicit allowlist. - Never interpolate node IDs into HTML attributes without encoding or validation. - If arbitrary rich markup is a functional requirement, sanitize it with a maintained allowlist-based sanitizer. - Move the XSS warning before the first HTML-node example and ensure every primary example is secure by default. Example URL validation: ```javascript function trustedImageURL(value) { const url = new URL(String(value), window.location.origin); if (url.protocol !== 'https:') { throw new Error('Unsupported image URL scheme'); } return url.href; } ``` Example safe node construction: ```javascript innerHTML: (d) => { const card = document.createElement('div'); const image = document.createElement('img'); image.src = trustedImageURL(d.data.avatar); image.width = 36; image.height = 36; const name = document.createElement('div'); name.textContent = String(d.data.name ?? ''); const role = document.createElement('div'); role.textContent = String(d.data.role ?? ''); card.append(image, name, role); return card; }, ``` ]]>

T09 · Insecure Skill Coding Practices

Error
Location
references/g6-graph-basic-usage.md:119
Finding
Basic Usage Examples Generate Unsafe Tooltip HTML<![CDATA[ ## Vulnerability Details **File Location**: `references/g6-graph-basic-usage.md:119-120` and `references/g6-graph-basic-usage.md:440-445` **Vulnerability Type**: Unescaped graph data inserted into tooltip HTML **Risk Level**: High ### Vulnerable Code ```javascript getContent: (e, items) => { return `<p>${items[0]?.id}</p>`; }, ``` The full tooltip example also interpolates data properties: ```javascript getContent: (e, items) => { let result = `<h4>Custom Content</h4>`; items.forEach((item) => { result += `<p>Type: ${item.data.description}</p>`; }); return result; }, ``` ### Technical Analysis The examples return HTML strings containing graph element IDs and descriptions without escaping. IDs should not be presumed safe merely because they identify graph records; externally supplied graph formats can contain attacker-controlled strings. If the G6 tooltip plugin interprets the return value as HTML, injected tags and event handlers are parsed by the browser. The examples provide no warning, sanitization, or safe DOM-based alternative at these locations. ### Attack Path 1. An attacker controls a graph element ID or description through an imported graph, API response, or stored record. 2. The victim opens the affected tooltip. 3. The callback concatenates the attacker-controlled property into an HTML string. 4. The tooltip renders the string as DOM content. 5. An injected event handler executes with the application's browser-origin privileges. ### Impact Assessment Exploitation can result in arbitrary client-side JavaScript execution. The attacker may read page-accessible data, issue authenticated same-origin requests, modify application state, or inject deceptive content. The resulting authority is bounded by the privileges of the victim's browser session and the affected origin. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Replace HTML string concatenation with an `HTMLElement` return value. - Use `textContent` for IDs, descriptions, and all other graph properties. - If the tooltip API requires a string, apply context-appropriate HTML escaping to every dynamic value. - Document that IDs are untrusted when graph records originate outside the source code. - Add regression tests for HTML payloads in IDs and descriptions. Example: ```javascript getContent: (event, items) => { const container = document.createElement('div'); for (const item of items) { const paragraph = document.createElement('p'); paragraph.textContent = `Type: ${String(item?.data?.description ?? '')}`; container.appendChild(paragraph); } return container; }, ``` ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (47)

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
This markdown skill forces a specific language/locale in its natural-language interface, beginning with the description and continuing in the main heading and guidance. Under the policy, language-specific behavior should either offer user choice or clearly document a justified locale constraint.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
前文在 L028-L032 明确说明 G6 v5 的 force 布局“不支持 preventOverlap / nodeSize”,应改用其他方式处理防重叠;但这里的基础模板却在 force 布局中直接使用了 `preventOverlap: true` 和 `nodeSize: 40`。这不是简单的遗漏,而是文档主动给出与自身约束相反的示例,容易误导使用者生成无效配置。

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
This markdown file contains the title, description, and tags only in Chinese, which effectively forces a specific language for users consuming the skill. The policy allows locale constraints only when users are given a choice or when the restriction is clearly documented and justified, neither of which appears here.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This file's title, description, tags, and examples are presented in Chinese, which imposes a specific language on users without any stated opt-in or alternative. The policy for this audit flags language or locale constraints when they are forced rather than optional or clearly justified.

Vague Triggers

Medium
Confidence
93% confidence
Finding
This markdown file states that focus is enabled by default for clicks on any element, but does not narrow the scope, list explicit trigger boundaries, or provide negative examples. Such a broad activation condition can overlap with normal graph interaction and lead to unintended invocation of the focus behavior.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The title and description require Chinese comprehension, and the rest of the document continues in Chinese-only instructional content. This can violate a language/locale policy when no user opt-in or explicit region-specific justification is provided.

External Transmission

Medium
Category
Data Exfiltration
Content
});

// 异步加载数据
fetch('https://api.example.com/graph-data')
  .then((res) => res.json())
  .then((data) => {
    graph.setData(data);     // 或在 render 前设置
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The title and description are written entirely in Chinese, and the rest of the document continues in Chinese without indicating that language selection is optional. Per the policy, forcing a specific language or locale without user opt-in is a natural-language policy violation unless the regional constraint is explicitly justified.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The title and description are entirely in Chinese, and the document provides no indication that language choice is optional or that the skill is intentionally limited to a Chinese-speaking context. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This file presents its title, description, headings, and instructional content only in Chinese. Under the policy rule, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly documented and justified, which is not present here.

External Transmission

Medium
Category
Data Exfiltration
Content
{
          name: '张三',
          role: '前端工程师',
          avatar: 'https://api.dicebear.com/7.x/miniavs/svg?seed=1',
        },
      },
      {
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
{
          name: '张三',
          role: '前端工程师',
          avatar: 'https://api.dicebear.com/7.x/miniavs/svg?seed=1',
        },
      },
      {
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The title and description require Chinese comprehension, and the rest of the document continues 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.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The title, description, tags, use cases, and instructional content are presented in Chinese, which effectively forces a specific language for users of the skill. Under the stated policy, locale or language restrictions should either be optional for the user or clearly justified as region-specific.

Natural-Language Policy Violations

Medium
Confidence
84% confidence
Finding
The title and description are entirely in Chinese, and the document does not indicate that language is optional or that the skill is intentionally limited to a Chinese-speaking context. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The title, description, section headings, and explanatory text are all presented in Chinese, and the file does not indicate that the user can opt into another language or that the skill is intentionally restricted to a Chinese-language audience. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The title, description, examples, and instructional text are entirely in Chinese, which imposes a specific language on users. The file does not indicate that the locale is optional, user-selectable, or required for a documented region-specific purpose.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
L196 的注释声称“通过在节点 style 中设置坐标来固定位置”,但紧随其后的示例仅为一个节点设置初始 x/y 坐标,真正用于“固定”的行为出现在 L203-L207 的 nodeFixable 回调中。设置初始坐标与固定节点是不同语义,这会误导使用者对代码实际效果的理解。

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The title and description are entirely in Chinese, and the document provides no indication that language selection is optional or that the content is intentionally limited to a Chinese-speaking audience. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
This file’s title and description force a specific language/locale for users, and the rest of the document continues in Chinese with no opt-in or alternative language indicated. Under the stated policy, forcing a specific language without user choice is a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The title, description, headings, tables, comments, and examples are written entirely in Chinese, with no indication that the skill is region-specific or that users may choose another language. Under the stated policy, forcing a specific language without opt-in is a natural-language policy violation.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
This markdown file documents a context menu that offers '删除节点' and '删除边' actions and shows code that immediately removes graph data when 'delete' is clicked. The surrounding documentation does not warn that these actions are destructive or suggest confirmation/undo safeguards, which is relevant for markdown files describing behavior that can affect user data.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The example constructs tooltip HTML by interpolating data fields directly into a template string and returns it for rendering. If node or edge data can contain attacker-controlled values, this can lead to DOM-based XSS in the tooltip, especially because the skill is documentation/code-generation guidance that may be copied into production without adding sanitization.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
This variant renders every key/value from the data object into HTML using Object.entries(...).map(...).join('') with no escaping. That broadens exposure because any field present in the object will be reflected into the DOM, making exploitation easier if any graph data originates from users, external systems, or mixed-trust sources.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The title and description are entirely in Chinese, and the rest of the skill continues in Chinese-only instructional text. For a general-purpose reference skill, this imposes a specific language/locale without any opt-in, alternative language, or stated region-specific justification, which matches the policy-violation criterion.

Static analysis

No suspicious patterns detected.