Back to skill

Security audit

Image-2 Skill

Security checks for vulnerabilities and agentic risk

Overview

This image-generation skill is purpose-aligned, but it needs Review because it can upload arbitrary readable local files or URLs to OpenAI and can save or overwrite files outside a dedicated output folder.

Install only if you are comfortable with the skill sending prompts, source images, masks, and URL-fetched image content to OpenAI. Use it in a restricted workspace, avoid sensitive local paths or private-network URLs, keep outputs inside a dedicated generated-images directory, and prefer a version that validates image types and sizes, blocks HTTP/private-network fetches, prevents overwrites, and pins dependencies.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/image-generator.js:98
Finding

Unrestricted Image Sources Permit SSRF and Arbitrary Local File Disclosure to OpenAI

Content
View full analysis
{ client.get(source, (response) => { const chunks = []; response.on('data', chunk => chunks.push(chunk)); response.on('end', () => { const buffer = Buffer.concat(chunks); resolve(buffer.toString('base64')); }); response.on('error', reject); }).on('error', reject); }); } ``` The resulting content is included in a request to OpenAI: ```javascript const base64 = await toBase64(imagePath); const mimeType = imagePath.toLowerCase().endsWith('.png') ? 'image/png' : 'image/jpeg'; const userContent = [ { type: 'image_url', image_url: { url: `data:${mimeType};base64,${base64}` } }, { type: 'text', text: `Edit this image: ${prompt}` } ]; if (maskPath) { const maskBase64 = await toBase64(maskPath); const maskMime = maskPath.toLowerCase().endsWith('.png') ? 'image/png' : 'image/jpeg'; userContent.unshift({ type: 'image_url', image_url: { url: `data:${maskMime};base64,${maskBase64}` } }); } const response = await client.chat.completions.create({ model: 'gpt-4o', messages: [{ role: 'user', content: userContent }] }); ``` ### Technical Analysis Both `imagePath` and `maskPath` reach `toBase64()` without a path boundary, URL allowlist, protocol restriction, address-range check, content-type check, or size limit. If the supplied string names any file readable by the Node.js process, `fs.readFileSync()` reads the entire file. Its contents are base64 ...[truncated 2263 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/image-generator.js:69
Finding

Exported Download Helper Allows Arbitrary File Overwrite and Insecure HTTP Content Injection

Content
View full analysis
{ const client = url.startsWith('https') ? https : http; client.get(url, (response) => { if (response.statusCode === 301 || response.statusCode === 302) { return downloadImage(response.headers.location, savePath).then(resolve).catch(reject); } if (response.statusCode !== 200) { return reject(new Error(`Download failed with status ${response.statusCode}`)); } const stream = fs.createWriteStream(savePath); response.pipe(stream); stream.on('finish', () => { stream.close(); resolve(savePath); }); stream.on('error', reject); }).on('error', reject); }); } ``` The helper is publicly exported: ```javascript module.exports = { generateImage, editImage, generateVariations, describeImage, downloadImage, batchGenerate, enhancePrompt, detectCategory, VALID_SIZES, VALID_MODELS, QUALITY_BOOSTERS, DEFAULTS }; ``` ### Technical Analysis `downloadImage()` accepts an unrestricted destination path, recursively creates its parent directories, and opens the destination with `fs.createWriteStream()`. By default, this truncates an existing file. There is no requirement that the destination remain inside `./generated-images` or another approved output directory. The function also accepts plaintext HTTP and follows redirects recursively without validating the redirect destination, limiting redirect depth, or requiring HTTPS. Therefore, an on-path attacker may replace downloaded content when HTTP is used, and an initially trusted endpoint can redirect to an untrusted or internal des ...[truncated 1769 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
README.md:143
Finding

Privacy Documentation Incorrectly Claims Images Are Not Stored Externally

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
package.json:21
Finding

Unpinned Dependency Without a Lockfile Creates Non-Reproducible Installations

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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 (11)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The manifest and documentation present the skill primarily as a GPT-4o image skill, but the documented behavior includes local filesystem writes and remote URL downloads that are not clearly declared as operational capabilities. This mismatch can mislead reviewers and users about data flow and side effects, increasing the risk of unexpected file creation, ingestion of attacker-controlled URLs, and broader trust in undeclared behavior.

Content

No source excerpt is available for this finding.

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/image-generator.js (reported line 198)May include surrounding context.

js
const boosterWords = booster.toLowerCase().split(', ');
  const newWords = boosterWords.filter(word => !lower.includes(word.split(' ')[0]));

  if (newWords.length === 0) return prompt;
  return `${prompt}, ${newWords.join(', ')}`;
}

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README fails to warn users that prompts and images are sent to OpenAI for remote processing. In an image-editing skill, inputs may contain sensitive personal, corporate, or copyrighted content, so omission of this disclosure can lead to unintended data exposure and policy non-compliance.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The README makes a materially misleading privacy claim by stating that no images are stored on external servers, despite the skill relying on OpenAI's hosted image API. Users may share sensitive images under a false assumption of local-only processing, creating privacy, compliance, and trust risks.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill declares access to an environment secret (OPENAI_API_KEY) but does not define an explicit tool/permission scope. That weakens least-privilege guarantees and makes the skill's runtime capabilities less transparent to operators and users, especially if the hosting platform relies on manifest-declared scopes for review or isolation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs sending user-supplied image files or URLs to GPT-4o Vision/OpenAI services without an explicit warning that external transmission occurs. Users may provide sensitive images assuming local-only processing, creating a privacy and compliance risk when personal, proprietary, or regulated content is uploaded to a third-party API.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The code reads local image files, base64-encodes them, and sends their contents to the OpenAI API for image analysis/editing. That behavior is core to the skill, but without an explicit user-facing disclosure or consent check at the operation site, users may unknowingly transmit sensitive local images off-host to a third-party service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The README describes editing capabilities that remove, replace, and extend image content but does not warn that edits may overwrite or alter user images if workflows are not handled carefully. While this is primarily a safety/usability issue rather than a code exploit, it can still cause accidental data loss or irreversible modification of important user assets.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The workflow states that generated images are downloaded and saved locally by default, but it does not prominently warn users about automatic file creation. This can cause unanticipated persistence of potentially sensitive or policy-relevant content on disk, especially in shared workspaces or ephemeral environments with unclear storage handling.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The dependency version for the OpenAI SDK is specified with a caret range (^4.0.0), which allows automatic installation of newer minor and patch releases. This creates supply-chain risk because future upstream changes or a compromised release could be pulled in without explicit review, reducing build reproducibility and making security regressions harder to control.

Content

Scanner excerpt · package.json (reported line 23)May include surrounding context.

json
"author": "",
  "license": "MIT",
  "dependencies": {
    "openai": "^4.0.0"
  },
  "engines": {
    "node": ">=16.0.0"

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The skill downloads remote image URLs returned by the API and writes them to local disk automatically. While expected for an image-generation skill, silently persisting remote content can surprise users, create storage of untrusted files, and increase risk if sensitive locations or filenames are chosen by the caller.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.