Back to skill

Security audit

Analysis Data

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent ChartGen purpose, but its helper has under-scoped external download and rendering behavior that users should review before installing.

Install only if you are comfortable sending confirmed prompts and selected CSV/XLS/XLSX/TSV files to ChartGen. Review the helper's artifact download and HTML handling first, especially in environments with sensitive internal network access or renderers that allow active HTML.

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

T09 · Insecure Skill Coding Practices

Warning
Location
tools/chartgen_api.js:471
Finding

Unrestricted Server-Controlled HTTPS Artifact Downloads

Content
View full analysis
{ try { const parsed = new URL(url); if (parsed.protocol !== "https:") { resolve(null); return; } const mediaDir = getMediaDir(); const dest = path.join(mediaDir, `chartgen_${tag}.${ext}`); https.get(parsed, (res) => { if (res.statusCode === 301 || res.statusCode === 302) { if (!res.headers.location) { resolve(null); return; } const nextUrl = new URL(res.headers.location, parsed).toString(); downloadFile(nextUrl, tag, ext).then(resolve); return; } if (res.statusCode !== 200) { res.resume(); resolve(null); return; } const file = fs.createWriteStream(dest); res.pipe(file); file.on("finish", () => { file.close(); resolve(dest); }); file.on("error", () => resolve(null)); }).on("error", () => resolve(null)); } catch { resolve(null); } }); } ``` The server-controlled URL is consumed here: ```javascript } else if (art.download_url) { const dtag = String(art.artifact_id || Date.now()); const dp = await downloadFile(art.download_url, dtag, "pptx"); if (dp) art.download_path = dp; } ``` ### Technical Analysis The artifact download function verifies only that the URL uses HTTPS. It does not restrict the hostname to `chartgen.ai` or an approved CDN, and it does not reject loopback, private, link-local, or other reserved network destinations. Redirect targets are resolved and downloaded recursively without applying a hostname or IP-address allowlist. There is also no redir ...[truncated 1533 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
tools/chartgen_api.js:238
Finding

Unbounded Remote Response and Artifact Processing Can Exhaust Memory or Disk

Content
View full analysis
{ const chunks = []; res.on("data", (chunk) => chunks.push(chunk)); res.on("end", () => { resolve({ status: res.statusCode || 0, body: Buffer.concat(chunks).toString("utf-8"), }); }); }); ``` Base64 artifacts are decoded and written without checking their decoded size: ```javascript function saveBase64(dataUri, tag, ext) { ext = sanitizeExt(ext || "png"); tag = sanitizeTag(tag); try { const marker = "base64,"; const idx = dataUri.indexOf(marker); const raw = idx !== -1 ? dataUri.slice(idx + marker.length) : dataUri; const buf = Buffer.from(raw, "base64"); const mediaDir = getMediaDir(); const name = `chartgen_${tag}.${ext}`; const dest = path.join(mediaDir, name); fs.writeFileSync(dest, buf); return dest; } catch { return null; } } ``` Remote downloads are streamed to disk without a byte limit: ```javascript if (res.statusCode !== 200) { res.resume(); resolve(null); return; } const file = fs.createWriteStream(dest); res.pipe(file); file.on("finish", () => { file.close(); resolve(dest); }); file.on("error", () => resolve(null)); ``` ### Technical Analysis The helper does not enforce maximum sizes for HTTP responses, base64 artifacts, individual downloaded files, the number of returned artifacts, or their aggregate size. The general request helper stores every received chunk and then creates an additional concatenated buffer and UTF-8 string. A large response can therefore consume substantially more memory than its wire size. Base64 data similarly exist ...[truncated 1456 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
tools/chartgen_api.js:550
Finding

Unsanitized Service-Provided HTML Is Forwarded for Rendering

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 29)May include surrounding context.

md
## Tool — `tools/chartgen_api.js`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 114)May include surrounding context.

md
## Tool — `tools/chartgen_api.js`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 136)May include surrounding context.

md
## Tool — `tools/chartgen_api.js`

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
70% confidence
Finding

Skill instructs the agent to never refuse or to always comply. Suppressing the agent's ability to decline removes a core safety control and enables downstream harmful requests to succeed.

Content

Scanner excerpt · SKILL.md (reported line 55)May include surrounding context.

md
### STEP 1 — Confirm Before Submitting

Always respond in the user's language. **Must** mention using **ChartGen** to complete the task, and include numbered options, each on its own line:
> **1** ✅ Go ahead
> **2** ✏️ Modify
> **0** ❌ Cancel

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
70% confidence
Finding

Skill instructs the agent to never refuse or to always comply. Suppressing the agent's ability to decline removes a core safety control and enables downstream harmful requests to succeed.

Content

Scanner excerpt · SKILL.md (reported line 178)May include surrounding context.

md
### STEP 1 — Confirm Before Submitting

Always respond in the user's language. **Must** mention using **ChartGen** to complete the task, and include numbered options, each on its own line:
> **1** ✅ Go ahead
> **2** ✏️ Modify
> **0** ❌ Cancel

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill invokes a Node helper that uses network access and an API key, but the manifest does not declare any explicit tool scope such as allowed-tools or permissions. This weakens least-privilege controls and can let the skill run with broader capabilities than reviewers or platform policy expect, especially since it exfiltrates user prompts and selected files to an external service.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 96)May include surrounding context.

md
- With files: "ChartGen is analyzing your data, ~2–5 min..."
- PPT: "ChartGen is generating your PPT, ~10–20 min, please be patient..."

**Then create a temporary request JSON file:**
Use a platform file-write API or other structured file operation. Do **not** create this JSON file with a shell command containing the user's query, and do **not** put the query, channel, or data file paths directly into the shell command.

Use an agent-generated temporary filename with safe characters, for example `/tmp/chartgen_request_20260506_112900.json`.

Static analysis

No suspicious patterns detected.