Back to skill

Security audit

Data Viz Suite

Security checks for vulnerabilities and agentic risk

Overview

This is a plausible data-visualization skill, but its generated HTML can run unsafe injected content and loads mutable third-party JavaScript without clear disclosure.

Install only if you trust the data being rendered and understand that generated dashboards may contact a third-party CDN when opened. Avoid using untrusted titles, table cells, KPI labels, or report text until the HTML escaping issues are fixed, and prefer pinned dependencies or a lockfile for reproducible installs.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/dashboard.py:73
Finding

Stored Cross-Site Scripting in Generated Dashboards

Content
View full analysis
{self.title} ...

{self.title}

""" ``` ```python value_str = f"{kpi['prefix']}{kpi['value']}{kpi['suffix']}" html += f"""
{kpi['title']}
{value_str}
{change_html}
""" ``` ```python for chart_id, chart_info in self.charts.items(): html += f"""
{chart_info['title']}
""" ``` ```python for table in self.tables: html += '
\n' html += f'

{table["title"]}

\n' html += ' \n \n' for col in table['columns']: html += f' \n' html += ' \n' for row in table['data'][:50]: html += ' \n' for col in table['columns']: val = row.get(col, '') html += f' \n' html += ' \n' ``` ```python html += '
{col}
{val}
Remediation
View remediation
`, `&`, U+2028, and U+2029 before embedding. 5. Prefer a template engine with automatic HTML escaping and explicitly distinguish HTML, attribute, JSON, and JavaScript contexts. 6. Add a restrictive Content Security Policy as defense in depth, avoiding `unsafe-inline` where feasible. 7. Add regression tests using payloads such as: - `` - `` - `');alert(1);//` 8. Verify that generated output displays these strings as text and does not create executable DOM nodes or break JavaScript syntax. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/report_generator.py:105
Finding

Stored Cross-Site Scripting in Generated HTML Reports

Content
View full analysis
{self.title} body {{ font-family: Arial, sans-serif; margin: 40px; }} h1 {{ color: #333; }} h2 {{ color: #555; margin-top: 30px; }} table {{ border-collapse: collapse; width: 100%; margin: 20px 0; }} th, td {{ border: 1px solid #ddd; padding: 12px; text-align: left; }} th {{ background-color: #f2f2f2; }}

{self.title}

""" for section in self.sections: html += f"

{section['title']}

\n" if section['text']: html += f"

{section['text']}

\n" if section['dataframe'] is not None: html += section['dataframe'].head(50).to_html(index=False) ``` ### Technical Analysis The report title, section titles, and section body text are directly interpolated into an HTML document without escaping. These fields are supplied through the public constructor and `add_section()` interface, so they can contain arbitrary HTML. An attacker can supply an element with an event handler, a script-closing sequence, or another active HTML payload. The payload is persisted in the exported report and interpreted by the browser when the report is opened. Pandas table output uses HTML escaping by default unless configured otherwise, but that behavior does not protect the separately interpolated report and section fields shown above. ### Attack Path 1. An attacker influences a report title, section title, or section text. 2. The application passes the value to `ReportGenerator()` or `add_section()`. 3. The application exports the report as ...[truncated 807 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/dashboard.py:75
Finding

Generated Dashboards Execute an Unpinned Remote JavaScript Dependency

Content
View full analysis
``` ### Technical Analysis Every generated dashboard loads `plotly-latest.min.js` from a third-party CDN when opened. The `latest` path is mutable and does not identify a reviewed, immutable release. The element also lacks a Subresource Integrity hash. Consequently, the JavaScript that executes is not fully represented by the audited project. Its contents can change after dashboard generation due to routine upstream updates, CDN compromise, account compromise, or supply-chain tampering. Because external scripts execute with the same browser privileges as the dashboard itself, compromise of the resource becomes compromise of the generated page. Opening a dashboard also makes an external network request that discloses ordinary connection metadata, such as the viewer's IP address and request headers, to the CDN. ### Attack Path 1. The application generates a dashboard containing the mutable CDN reference. 2. The Plotly CDN resource changes or is compromised after the dashboard or Skill has been reviewed. 3. A victim opens the generated dashboard while connected to the network. 4. The browser downloads the current contents of `plotly-latest.min.js`. 5. The browser executes that remote code with the privileges of the dashboard page. ### Impact Assessment A compromised dependency can execute arbitrary JavaScript in every generated dashboard that loads it. It can read and alter dashboard data, falsify visualizations, observe user interactions, and make requests permitted by the dashboard's browser origin. The dependency also creates an availability risk: dashboards may fail to render when the CDN is unavailable, blocked, or changes incompatibly. ...[truncated 81 chars]
Remediation
View remediation
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
Findings (28)

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

描述覆盖范围明显大于代码实际功能。该代码块的核心能力是基础图表生成与静态导出,属于数据可视化子集;但声明中的“企业级BI工具”“数据报表”“交互式仪表盘”“多种引擎支持”在此代码中均未得到体现。没有发现额外越权或可疑资源访问行为,但描述与实际行为存在实质性不一致,因此应判定为 mismatch。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

声明描述强调“数据可视化套件”和“企业级BI工具”,核心能力应包括图表生成、可视化引擎支持以及交互式仪表盘。但提供的代码只是在本地组织章节内容,并把文本与表格数据导出为 PDF/HTML/Excel。虽然 add_section 接收 charts 参数,但在 PDF/HTML/Excel 导出过程中完全没有渲染图表,也没有调用 Plotly、Matplotlib、Seaborn。不存在仪表盘、交互交互逻辑、查询分析或可视化编排能力。因此,代码的实际主要用途与声明存在实质性偏差。

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The natural-language content of the skill description and examples is written in Chinese, and there is no indication that users may choose another language or that the skill is intentionally region-specific. Per SQP-3, forcing a specific language without user opt-in is a policy concern unless the locale restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This Python file contains its title, comments, docstrings, data labels, and console output entirely in Chinese, including the main user-facing messages. Under the policy for natural-language violations, forcing a specific language without user opt-in or a documented regional justification is a reportable issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The natural-language descriptions in the module and class docstrings are written entirely in Chinese, presenting the skill as Chinese-localized by default with no indication that users may choose another language. Under the language/locale policy, forcing a specific language without opt-in can be a policy violation unless the locale restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The module title, class docstrings, and user-facing strings are written exclusively in Chinese, with no indication that the user can choose another language or locale. This creates a natural-language policy issue when the skill is expected to support user choice rather than imposing a fixed language by default.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The generated HTML loads Plotly from an external CDN at runtime, which introduces an unnecessary third-party network dependency into a local dashboard artifact. This can leak client metadata, break in offline/restricted environments, and creates supply-chain risk if the CDN resource is unavailable or tampered with; in this file, the risk is increased because the dashboard otherwise appears intended to be self-contained HTML output.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The module title, class/docstrings, and default report content are explicitly Chinese-language oriented (for example '报表生成器', '数据报表'), and the code preferentially registers Chinese fonts. There is no natural-language indication that language is configurable or that this is a region-specific tool, which can violate language/locale policy requiring opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The module docstring and test/doc comments are written in Chinese throughout, which imposes a specific language on maintainers or users of the skill without any opt-in or stated regional justification. Under the policy, language-specific behavior is only acceptable when the skill offers a language choice or clearly documents why the locale restriction is required.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README presents the skill description and usage guidance entirely in Chinese, aside from the title, with no indication that users may choose another language. This can violate a language/locale policy when a skill imposes a specific language without opt-in or documented regional justification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The examples encourage writing files such as sales.html, dashboard.html, and report.pdf without warning that local files will be created or possibly overwritten. In an agent context, implicit artifact creation can cause accidental data leakage, overwrites, or clutter in sensitive working directories if users do not realize outputs are persisted.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency is specified with a lower-bound only (plotly>=5.15.0), which allows future unreviewed versions to be installed. This weakens build reproducibility and can silently introduce vulnerable or breaking releases through the supply chain.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
plotly>=5.15.0
matplotlib>=3.7.0
seaborn>=0.12.0
pandas>=2.0.0

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency is unpinned (matplotlib>=3.7.0), so installs may resolve to different versions over time. That increases supply-chain risk and makes it harder to verify that only tested, non-vulnerable versions are deployed.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
plotly>=5.15.0
matplotlib>=3.7.0
seaborn>=0.12.0
pandas>=2.0.0
numpy>=1.24.0

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

Using seaborn>=0.12.0 permits any later release, including versions not yet vetted by the skill author. This creates a dependency integrity and reproducibility issue rather than an immediate exploit by itself.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
plotly>=5.15.0
matplotlib>=3.7.0
seaborn>=0.12.0
pandas>=2.0.0
numpy>=1.24.0
kaleido>=0.2.0

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The pandas requirement is not pinned to a specific version, so environments may pull different releases with different security properties. In a data-processing skill, this matters because pandas often handles untrusted files and data inputs.

Content

Scanner excerpt · requirements.txt (reported line 4)May include surrounding context.

text
plotly>=5.15.0
matplotlib>=3.7.0
seaborn>=0.12.0
pandas>=2.0.0
numpy>=1.24.0
kaleido>=0.2.0
openpyxl>=3.1.0

Unverifiable Dependency: pandas has 1 known advisory(ies) (CVE-2020-13091 (** DISPUTED ** pandas through 1.0.3 can unserialize and execute commands from an)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
92% confidence
Finding

Because pandas is not pinned, it is impossible to verify from this manifest whether the installed version includes a vulnerable release mentioned in advisories. In a data-visualization skill that may ingest external datasets, inability to prove a safe version increases operational risk.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The numpy dependency is unpinned, allowing uncontrolled upgrades to future versions. Although this is not direct code execution on its own, it increases exposure to vulnerable or incompatible transitive behavior.

Content

Scanner excerpt · requirements.txt (reported line 5)May include surrounding context.

text
matplotlib>=3.7.0
seaborn>=0.12.0
pandas>=2.0.0
numpy>=1.24.0
kaleido>=0.2.0
openpyxl>=3.1.0
reportlab>=3.6.0

Unverifiable Dependency: numpy has 16 known advisory(ies) (CVE-2014-1859 (Numpy arbitrary file write via symlink attack); CVE-2021-41495 (NumPy NULL Pointer Dereference); CVE-2021-33430 (NumPy Buffer Overflow (Disputed)) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
94% confidence
Finding

The manifest does not identify which numpy version will actually be installed, so known advisories cannot be ruled out. This is a supply-chain visibility problem that becomes more relevant in data-heavy components using native extensions.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

kaleido>=0.2.0 is a floating dependency and can resolve differently across installations. That creates supply-chain uncertainty and may introduce untested binaries or behavior into rendering/export workflows.

Content

Scanner excerpt · requirements.txt (reported line 6)May include surrounding context.

text
seaborn>=0.12.0
pandas>=2.0.0
numpy>=1.24.0
kaleido>=0.2.0
openpyxl>=3.1.0
reportlab>=3.6.0
jupyter>=1.0.0

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The openpyxl dependency is not pinned, which is more notable because spreadsheet parsers commonly process externally supplied files. This makes version-specific security validation difficult and can expose deployments to known parser flaws if an affected release is installed.

Content

Scanner excerpt · requirements.txt (reported line 7)May include surrounding context.

text
pandas>=2.0.0
numpy>=1.24.0
kaleido>=0.2.0
openpyxl>=3.1.0
reportlab>=3.6.0
jupyter>=1.0.0

Unverifiable Dependency: openpyxl has 2 known advisory(ies) (CVE-2017-5992 (Improper Restriction of XML External Entity Reference in Openpyxl); CVE-2017-5992 (Openpyxl 2.4.1 resolves external entities by default, which allows remote attack)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
96% confidence
Finding

openpyxl has known security history involving XML handling, and the unpinned manifest prevents verification that a safe version is installed. Since BI tools commonly import spreadsheets from users, this context makes the issue more dangerous than a generic library mismatch.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
99% confidence
Finding

reportlab is unpinned despite a history of serious advisories, and this library often processes rich document content. In a BI/report-generation skill, that raises the risk that a vulnerable release could be installed and later exposed through PDF generation paths.

Content

Scanner excerpt · requirements.txt (reported line 8)May include surrounding context.

text
numpy>=1.24.0
kaleido>=0.2.0
openpyxl>=3.1.0
reportlab>=3.6.0
jupyter>=1.0.0

Unverifiable Dependency: reportlab has 8 known advisory(ies) (CVE-2023-33733 (Reportlab vulnerable to remote code execution); CVE-2020-28463 (Server-side Request Forgery (SSRF) via img tags in reportlab); CVE-2019-19450 (ReportLab vulnerable to remote code execution via paraparser) +5 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
98% confidence
Finding

reportlab has multiple serious past advisories, including code execution and SSRF-related issues, and the unpinned dependency means the deployed version cannot be verified as safe. In a reporting suite that generates PDFs or rich documents, this materially increases risk if attacker-controlled content can reach rendering functions.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The jupyter package is unpinned, allowing future unreviewed versions to be installed. While not necessarily used in production, notebook-related packages expand the dependency footprint and increase supply-chain uncertainty.

Content

Scanner excerpt · requirements.txt (reported line 9)May include surrounding context.

text
kaleido>=0.2.0
openpyxl>=3.1.0
reportlab>=3.6.0
jupyter>=1.0.0

Static analysis

No suspicious patterns detected.