Back to skill

Security audit

article-images-gen

Security checks for vulnerabilities and agentic risk

Overview

This article illustration skill is purpose-aligned overall, but it uses unsafe shell command construction and automatically edits article files, so it needs review before installation.

Install only if you are comfortable with article text being sent to Gemini/Grok through browser automation and with the tool modifying article files. Run it on trusted articles and paths only, review backups, and prefer a fixed version that replaces exec with spawn/execFile argument arrays and requires explicit opt-in for in-place article edits.

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
scripts/image-generator.ts:62
Finding

Shell Command Injection Through Prompts and Output Paths

Content
View full analysis
{ const cmd = `opencli gemini image "${escapeShell(prompt)}" --rt ${ar} --op "${escapeShell(outDir)}" -f json --timeout 300`; const { stdout } = await execAsync(cmd, { timeout: 310_000 }); let parsed: any; try { parsed = JSON.parse(stdout); } catch { // Try to find JSON in output (opencli may emit logs before JSON) const jsonMatch = stdout.match(/\[[\s\S]*\]|\{[\s\S]*\}/); if (!jsonMatch) throw new Error(`Gemini: could not parse JSON output: ${stdout.slice(0, 500)}`); parsed = JSON.parse(jsonMatch[0]); } // opencli gemini image output columns: status, file, link const items = Array.isArray(parsed) ? parsed : parsed.results || parsed.images || [parsed]; const success = items.find((item: any) => item.status === "success" || item.file); if (!success?.file) { throw new Error(`Gemini: no successful image in output. Status: ${JSON.stringify(items.slice(0, 2))}`); } const imagePath = success.file as string; console.log(` ✓ Gemini image saved: ${imagePath}`); return { imagePath }; } async function runGrokImage( prompt: string, outDir: string ): Promise<{ imagePath: string }> { const cmd = `opencli grok image "${escapeShell(prompt)}" --out "${escapeShell(outDir)}" -f json --timeout 300 --count 1`; const { stdout } = await execAsync(cmd, { timeout: 310_000 }); let parsed: any; try { parsed = JSON.parse(stdout); } catch { const jsonMatch = stdout.match(/\[[\s\S]*\]|\{[\s\S]*\}/); if (!jsonMatch) throw new Error(`Grok: could not parse JSON output: ${stdout.slice(0, 500)}`); parsed = JSON.parse(jsonMatch[0]); } // opencli grok im ...[truncated 3683 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (14)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
bun scripts/illustrator.ts path/to/article.md [--density <level>] [--output-dir <path>]

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/article-analyzer.ts (reported line 155)May include surrounding context.

ts
promptFiles.push(filePath);
  }

  return promptFiles;
}

function buildHandDrawnPrompt(articleContent: string, illustrationDesc: string, sectionTitle: string): string {

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding

The skill documents network-dependent behavior and browser automation against external services, but it does not declare any explicit tool scope or permissions boundary. This creates an authorization and transparency gap: an agent may invoke broader capabilities than users expect, making outbound access and related side effects harder to audit or constrain.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill states that it uses external browser-based image generation services, but it does not warn that prompts derived from the article may be transmitted to third parties. This can leak sensitive or unpublished content from the article into external systems without informed user consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The documented 'full automatic' workflow says it will update the article by inserting image references, but it provides no warning that the source file will be changed. Silent modification of user content is dangerous because it can overwrite work, introduce unwanted edits, and violate user expectations about read-only processing.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest frames the skill as an illustration generator, but the workflow also edits the source article by inserting image references. This is a meaningful side effect beyond the stated purpose, and users or orchestrators may invoke the skill expecting image creation only, not file modification.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

The skill relies on browser automation to interact with external sites for image generation, which expands the attack surface beyond a simple local illustration helper. Even if intended for legitimate use, external browser-driven workflows can expose article-derived content to third parties and introduce risks from remote services, session state, or unintended navigation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The generated illustration prompt is entirely written in Chinese, which imposes a specific language on downstream use. The file does not provide any user opt-in, configuration, or justification that this skill is intentionally limited to Chinese-language workflows.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The top-of-file natural-language description is entirely in Chinese and presents the tool as a fixed Chinese-language skill, with no indication that users may choose another language or locale. This can violate language/locale policy when a skill imposes a specific language without documented opt-in or justification.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script rewrites the original article in place by inserting image references and only creates a best-effort timestamped backup beforehand. This is dangerous because a tool described as an illustration generator performs unexpected source-file mutation, which can corrupt content, introduce unwanted links, or overwrite user data if the article path points to an important file or symlinked target.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest describes a skill for generating hand-drawn article illustrations, but the implementation uses child_process.exec to launch external commands. While using an image backend is expected, arbitrary shell execution capability is broader than the stated purpose and introduces execution behavior not reflected in the skill description.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill exposes a generic downloadImage(url, outputPath) helper that can fetch arbitrary remote content and write it anywhere permitted on disk. That is broader than the stated illustration-generation purpose and can be abused for SSRF-style internal URL access, untrusted content retrieval, or planting attacker-controlled files in local paths.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This function performs arbitrary network fetches and persists the response to a caller-controlled path without validating destination or source. In the context of an image skill, that extra capability is dangerous because it can be repurposed to access internal services, download unexpected payloads, or overwrite files within writable directories.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The downloadImage function fetches remote content and writes it to a caller-specified local path, which is a safety-relevant file write operation. Although the file has some comments and logs for image generation, this specific write path has no confirmation prompt, logging, or user-facing disclosure in the code shown.

Content

No source excerpt is available for this finding.