Back to skill

Security audit

Intelligent data analysis report generator

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it claims, but generated reports can execute unsafe JavaScript from spreadsheet-derived names and also load external code from a CDN.

Review this skill carefully before installing. It is suitable only for trusted spreadsheets or reports opened in a controlled browser context, because malicious column names or generated labels could run JavaScript in the HTML report. Prefer a version that escapes all report data, removes eval, bundles or integrity-pins ECharts, and clearly manages temporary output files.

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
assets/report_template.html:237
Finding

Stored HTML and JavaScript Injection in Generated Reports

Content
View full analysis
{{REPORT_TITLE}}
{{REPORT_SUBTITLE}}
...
{{INSIGHTS}}
``` ```javascript (function renderSummaryCards() { const container = document.getElementById('summary-cards'); if (!SUMMARY_STATS || Object.keys(SUMMARY_STATS).length === 0) { container.style.display = 'none'; return; } const entries = Object.entries(SUMMARY_STATS); const displayCols = entries.slice(0, 5); container.innerHTML = displayCols.map(([key, val]) => `
${key}
${formatNum(val.mean)}
Range: ${formatNum(val.min)} – ${formatNum(val.max)}
`).join(''); })(); ``` ```javascript const rows = Object.entries(stats).map(([name, s]) => { const cells = [name, s.mean, s.median, s.std, s.min, s.max, s.sum, s.cv].map(v => typeof v === 'number' ? formatNum(v) : (v || '-') ); return '' + cells.map(c => `${c}`).join('') + ''; }).join(''); ``` ```javascript return `
${chart.title}
`; ... sectionContainer.innerHTML = html; ``` Spreadsheet column names are preserved by the analyzer: ```python for col in df.columns: ctype = detect_column_type(df[col], col) dtype = str(df[col].dtype) unique = int(df[col].nunique()) columns_info.append({ "name": str(col), "type": ctype, "dtype": dtype, "unique": unique, "missing": int ...[truncated 2404 chars]
Remediation
View remediation
`, `&`, U+2028, and U+2029. Prefer loading JSON from an `application/json` element and parsing its `textContent`. 4. Sanitize `INSIGHTS` with a strict allowlist if formatted HTML is required. Otherwise, render insights as plain text. 5. Generate chart element IDs internally and restrict them to a safe character set rather than deriving them from column names. 6. Add a restrictive Content Security Policy that disallows inline event handlers and limits script sources. Remove inline scripting where practical. 7. Add regression tests using malicious column names, including HTML elements, quotes, closing script tags, and encoded variants. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
assets/report_template.html:346
Finding

Attacker-Influenced Dynamic Code Execution Through eval

Content
View full analysis
{ const cid = 'chart_' + id; chartInitCode += ` (function() { var dom = document.getElementById('${cid}'); if (dom && dom.clientWidth > 0) { var chart = echarts.init(dom); chart.setOption(${JSON.stringify(chart.option)}); chart.resize(); } })();`; return `
${chart.title}
`; }).join(''); ``` ```javascript sectionContainer.innerHTML = html; // Initialize ECharts (use requestAnimationFrame to ensure DOM is rendered) requestAnimationFrame(() => { requestAnimationFrame(() => { eval(chartInitCode); }); }); ``` Chart identifiers can contain metric names derived from the input file: ```python for mc in metric_cols[:2]: charts.append({ "id": f"pie_{mc}", "title": f"{mc} Distribution by {dim_cols[0]}", "type": "pie", "description": f"Proportion of {mc} across {dim_cols[0]} categories", }) ``` ```python for mc in metric_cols[:3]: charts.append({ "id": f"line_{mc}", "title": f"{mc} Trend Over Time", "type": "line", "description": f"Time series trend of {mc}", }) ``` ### Technical Analysis The template builds JavaScript source code as a string and executes it with `eval`. Chart IDs are based on object keys generated from metric column names. Those metric names originate in the uploaded spreadsheet and are not restricted to a safe identifier character set. The value is interpolated inside a single-quoted JavaScrip ...[truncated 1394 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:127
Finding

Unpinned Python Dependencies and CDN Script Without Integrity Verification

Content
View full analysis
``` The chart guidance repeats the same remote dependency: ```markdown ## ECharts CDN Use the following CDN for ECharts in HTML templates: ```html ``` ``` ### Technical Analysis The recommended `pip install` command does not pin package versions or verify artifact hashes. Every installation can therefore resolve to different package releases. If a package publisher account, package release, dependency, package index, or delivery path is compromised, installation may execute attacker-controlled package build or installation logic. The generated report loads ECharts from a third-party CDN at viewing time. Although the URL includes version `5.5.0`, the script element has no Subresource Integrity metadata. The browser therefore cannot verify that the downloaded bytes match an expected artifact. The report is also described as self-contained, but this external runtime dependency means its executable behavior depends on remote content and network availability. No evidence was found that the named packages or CDN URL are intentionally malicious. The finding concerns missing supply-chain controls rather than a confirmed malicious dependency. ### Attack Path #### Python Dependency Path 1. A user runs the documented installation command because dependencies are unavailable. 2. `pip` resolves the latest compatible versions from its configured package index. 3. A compromised release, transitive dependency ...[truncated 1052 chars]
Remediation
View remediation
Vulnerability Patterns
  • 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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The code substantially matches the data-ingestion and analysis portion of the description: it reads Excel/CSV, identifies likely dimensions/metrics/timelines, computes descriptive statistics, correlations, timeline aggregations, and top-N breakdowns. However, the declared purpose prominently claims generation of professional HTML reports with ECharts interactive charts, and no such functionality exists in the code. The script is a backend analysis engine/CLI that emits JSON only. This is a material description-to-behavior mismatch because a key user-facing capability—HTML report and chart generation—is absent.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The supplied code chunk is narrowly focused on chart configuration generation. It selects chart types from fields already present in an analysis object and builds ECharts option payloads for bar, pie, line, scatter, heatmap, and summary table outputs. Its input is a JSON analysis file, not raw Excel/CSV data, and there is no code for parsing spreadsheets/CSVs, detecting dimensions/metrics/timelines from source data, or conducting the substantive analysis itself. It also does not render or assemble HTML reports; it only emits JSON chart configs and style metadata. While chart generation is consistent with part of the description, the declared purpose significantly overstates this specific code chunk's behavior.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill instructs the agent to read input files and write intermediate JSON and final HTML outputs, but it does not declare any explicit tool scope or permissions boundary. This can cause the agent to operate with broader-than-expected file access, reducing transparency and making accidental access or modification of workspace files more likely.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger phrases are broad enough that the skill could be invoked for generic mentions of reports or Excel/CSV analysis without clear user intent. In this skill, unintended invocation matters because it leads to reading user files and creating derived artifacts, which can surprise users and expand data handling beyond what they expected.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The workflow explicitly writes intermediate analysis artifacts and a final HTML report into the workspace, but the skill description does not warn users about this persistence. Undisclosed file creation can expose sensitive derived data to later sessions, other tools, or accidental sharing, especially when analysis output contains statistics or business insights from confidential spreadsheets.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The generated HTML loads ECharts from a CDN, introducing a network dependency that can leak access metadata such as IP address, user agent, timing, and referrer context when the report is opened. In a data-reporting skill, this is more sensitive because reports may be opened in regulated or confidential environments where even metadata disclosure or third-party content loading is unacceptable.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The HTML document is explicitly marked as lang="zh-CN", which forces a specific locale for the generated report. Under the policy, locale constraints should not be imposed unless the user is given a choice or the restriction is clearly documented and justified.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The template loads executable JavaScript from a third-party CDN at report-view time, which introduces a supply-chain and privacy risk. If the CDN content is compromised, blocked, or altered, anyone opening the generated report may execute untrusted code and leak viewing metadata despite this being a local report generator.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The number formatter appends the Chinese unit 万, which bakes Chinese-language formatting into generated output. This is a natural-language locale choice embedded in code, and there is no evidence here of user selection or documented justification.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest describes a data analysis report generator that analyzes Excel/CSV data and generates reports, but this script also performs filesystem writes to any caller-supplied output path. While producing output is related to analysis, the manifest text emphasizes analysis/report generation rather than general file modification behavior, so the write capability is broader than the code documentation and stated analyzer role suggest.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The entry for the 36Kr style specifies 'Chinese-friendly' fonts, which imposes a locale/language-specific presentation choice in natural language. The file does not indicate that this locale-specific styling is optional, user-selected, or limited to Chinese-language reports, so it may conflict with a policy requiring language/locale choice or explicit justification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

This code performs a file write via the --output path, which can modify or overwrite local files. Although the CLI exposes the output option, there is no confirmation prompt or explicit warning message near the write operation about the data-changing effect.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.