Back to skill

Security audit

Image Generation

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent diagram/image tooling, but its interactive local diagram server can persist and change sessions without authentication, so it should be reviewed before installation.

Install only if you are comfortable with helper scripts that run local Node tools, launch a local browser for export, call local image converters for JPEG output, and optionally start a loopback diagram server. Avoid putting sensitive architecture, PII, credentials, or unreleased business details into the interactive server, use unique session IDs, keep the server bound to 127.0.0.1, and stop it when finished.

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

Warning
Location
scripts/interactive-diagram-server.mjs:2
Finding

Unauthenticated Loopback API Permits Cross-Origin Diagram State Modification

Content
View full analysis

Vulnerability Details

File Location: scripts/interactive-diagram-server.mjs, lines 2–10
Vulnerability Type: Unauthenticated state-changing HTTP API / localhost cross-origin request abuse
Risk Level: Medium

Vulnerable Code

js
const N=G.createServer((t,e)=>{Z(t,e)});

async function Z(t,e){
  const o=new URL(t.url??"/",`http://${t.headers.host??"127.0.0.1"}`),
        r=q(o.searchParams.get("s")??"default");
  try{
    if(t.method==="GET"&&o.pathname==="/")K(e);
    else if(t.method==="GET"&&o.pathname==="/events")Q(r,e);
    else if(t.method==="GET"&&o.pathname==="/state")h(e,200,b(r).commands);
    else if(t.method==="GET"&&o.pathname==="/status")h(e,200,nt());
    else if(t.method==="GET"&&o.pathname==="/sessions")h(e,200,ot());
    else if(t.method==="POST"&&o.pathname==="/cmd")await V(t,e,r);
    else if(t.method==="POST"&&o.pathname==="/clear")
      et(r),h(e,200,{ok:!0,session:r,commands:0});
    else if(t.method==="GET"&&o.pathname==="/export")
      O(e,r,o.searchParams.get("format")??"json");
    else if(t.method==="POST"&&o.pathname==="/export"){
      const n=await A(t),
            s=typeof n.format=="string"?n.format:"json";
      O(e,r,s)
    } else h(e,404,{ok:!1,error:`Unknown route ${t.method??"GET"} ${o.pathname}`})
  }catch(n){
    h(e,500,{ok:!1,error:n instanceof Error?n.message:String(n)})
  }
}

async function V(t,e,o){
  let r;
  try{r=await A(t)}
  catch(s){
    h(e,400,{ok:!1,error:s instanceof Error?s.message:String(s)});
    return
  }
  if(!P(r)){
    h(e,400,{ok:!1,error:"Body must be a JSON object with a string cmd field"});
    return
  }
  const n=b(o);
  r.cmd==="clear"?n.commands=[]:
  r.cmd==="init"?n.commands=[r]:
  n.commands.push(r),
  F(o,n.commands),
  R(n,r),
  h(e,200,{ok:!0,session:o,commands:n.commands.length})
}

function P(t){
  return!!(t&&typeof t=="object"&&typeof t.cmd=="string")
}

Technical Analysis

The interactive diagram server exposes state-changing endpoints such as `/cm ...[truncated 3072 chars]

Remediation
View remediation

Remediation Suggestions

  1. Generate a cryptographically random capability token when the server starts and require it for every API, SSE, state, and export request.
  2. Generate a separate high-entropy token for each diagram session instead of treating a human-readable session name as authorization.
  3. Reject requests with missing or unexpected Origin headers. Allow only the server’s own loopback origin.
  4. Validate the Host header against the actual loopback listener and reject unexpected hostnames.
  5. Require Content-Type: application/json for command requests and reject other media types. This adds a browser preflight barrier, although it must not replace authentication.
  6. Implement a restrictive CORS policy and do not return permissive cross-origin headers.
  7. Remove the predictable default session or map it internally to an unguessable session capability.
  8. Consider disabling automatic adjacent-port fallback. Otherwise, include the capability only in the exact startup URL and ensure it is required on every fallback port.
  9. Add CSRF-focused regression tests covering cross-origin simple POST requests to /cmd and /clear.
  10. Optionally bind each server instance to one session and terminate it automatically after inactivity or successful export to reduce the exposure window.
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 (14)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
l-technical-diagrams.md), then render JSON IR with [tech-diagram-render.mjs](scripts/tech-diagram-render.mjs). For process workflows, model participants as `lan

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
are needed from generated HTML/SVG sources, export with [export-diagram.mjs](scripts/export-diagram.mjs):

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- For live interactive sketches, start [interactive-diagram-server.mjs](scripts/interactive-diagram-server.mjs), open the served [interactive-diagram.html](asse

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
/interactive-diagram-server.mjs), open the served [interactive-diagram.html](assets/interactive-diagram.html) page with a unique `?s=session-id`, then POST smal

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- [diagram-layout.mjs](scripts/diagram-layout.mjs)

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 10)May include surrounding context.

md
- ID: `fec-image-generation`
- Category: `design-ui`
- Version: `2.9.0`
- Source: `skills/fec-image-generation/SKILL.md`

## Description

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
85% confidence
Finding

The skill instructs the agent to run multiple local scripts and a local HTTP server, but it declares no explicit tool scope or permissions boundary. In practice this increases the chance that an agent with broader-than-necessary capabilities can access environment data or execute unintended commands during the workflow, violating least privilege.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

md
- For live interactive sketches, start [interactive-diagram-server.mjs](scripts/interactive-diagram-server.mjs), open the served [interactive-diagram.html](assets/interactive-diagram.html) page with a unique `?s=session-id`, then POST small JSON commands to `/cmd?s=session-id`:
     ```bash
     node skills/fec-image-generation/scripts/interactive-diagram-server.mjs --port 6100
     curl -s "http://127.0.0.1:6100/cmd?s=checkout-flow" -d '{"cmd":"init","title":"Checkout Flow","direction":"TB"}'
     curl -s "http://127.0.0.1:6100/cmd?s=checkout-flow" -d '{"cmd":"node","id":"cart","label":"Review cart","type":"process"}'
     ```
   - Use the draw.io studio workflow instead when the priority is editable `.drawio` source, official diagrams.net shapes, or long-term manual editing.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The page makes network requests to /state and opens a live EventSource connection to /events, allowing remote server-driven state synchronization rather than purely local diagram generation/editing. In a skill intended for image/diagram generation, this expands the trust boundary: remote data can continuously modify the UI and exported artifacts, and if session identifiers are guessable or shared, diagrams may be exposed or tampered with across sessions.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest description uses very broad activation language ('Use when generating or editing diagrams, charts, visual assets, posters, UI mockups, product images...') that can cause the agent to invoke this skill for a wide range of common design tasks beyond narrowly scoped diagram/image workflows. Over-broad routing increases the chance that this skill is selected in inappropriate contexts, which can override safer or more specialized skills and lead to unintended file generation, editing, or autonomous repair behavior.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest describes diagram/image generation and export with browser-based QA, but this script also shells out to locally installed converters such as ImageMagick, FFmpeg, macOS sips, and PowerShell/System.Drawing to produce JPEG output. Spawning arbitrary external executables is a materially broader capability than the manifest suggests, even if used here for format conversion.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This script invokes local executables such as ImageMagick, FFmpeg, PowerShell, and sips to convert images, which is a safety-relevant system operation. The file has no confirmation prompt, warning comment, or user-facing disclosure that external commands may be executed during JPEG export.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The generated HTML template hard-codes the document language to English. That is a natural-language locale choice without any opt-in or explanation, which may violate language/locale policy expectations for universally applicable skills.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The server writes session command data to disk via writeFileSync, persisting user-provided diagram commands under the system temp directory. There is no confirmation prompt, warning log, or explanatory comment near this operation to disclose that data is being stored locally.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.