Back to skill

Security audit

Generate Presentation

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its presentation-building purpose, but its bundled image tool can read and upload arbitrary local files and overwrite arbitrary writable files, which needs Review before installation.

Install only in an isolated project or container with a least-privileged API key. Treat slide text, prompts, fetched URL content, and edited source images as data that may be sent to OpenAI or Azure OpenAI. Do not expose the MCP server to untrusted callers, restrict image input/output paths before use, avoid sensitive local files in the same account, protect .env files, and update or pin dependencies before production use.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
mcp-servers/openai-gpt-image/src/index.ts:202
Finding

Unrestricted Local File Read and External Upload Through edit-image

Content
View full analysis
{ if (!val) return true; // Check for Unix/Linux/macOS absolute paths if (val.startsWith("/")) return true; // Check for Windows absolute paths (C:/, D:\, etc.) if (/^[a-zA-Z]:[/\\]/.test(val)) return true; return false; }; const imageInputSchema = z.string().refine( (val) => absolutePathCheck(val) || base64Check(val), { message: "Must be an absolute path or a base64-encoded string (optionally as a data URL)" } ).describe("Absolute path to an image file (png, jpg, webp < 25MB) or a base64-encoded image string."); const editImageBaseSchema = z.object({ image: z.string().describe("Absolute image path or base64 string to edit."), prompt: z.string().max(32000).describe("A text description of the desired edit. Max 32000 chars."), mask: z.string().optional().describe("Optional absolute path or base64 string for a mask image (png < 4MB, same dimensions as the first image). Fully transparent areas indicate where to edit."), model: z.enum(["gpt-image-1.5", "gpt-image-1", "gpt-image-1-mini"]).default("gpt-image-1.5"), n: z.number().int().min(1).max(10).optional().describe("Number of images to generate (1-10)."), quality: z.enum(["auto", "high", "medium", "low"]).optional().describe("Quality (high, medium, low) - only for gpt-image-1."), size: z.enum(["1024x1024", "1536x1024", "1024x1536", "auto"]).optional().describe("Size of the generated images."), user: z.string().optional().describe("Optional user identifier for OpenAI monitoring."), output: z.enum(["base64", "file_output"]).default("base64").describe("Output format: base64 or file path."), file_output: z.string().refine(absolutePathCheck, { message: "Path must ...[truncated 3690 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
mcp-servers/openai-gpt-image/src/index.ts:67
Finding

Arbitrary File Overwrite Through Unrestricted file_output Paths

Content
View full analysis
{ if (!val) return true; // Check for Unix/Linux/macOS absolute paths if (val.startsWith("/")) return true; // Check for Windows absolute paths (C:/, D:\, etc.) if (/^[a-zA-Z]:[/\\]/.test(val)) return true; return false; }, { message: "file_output must be an absolute path" } ).describe("Absolute path to save the image file, including the desired file extension (e.g., /path/to/image.png). If multiple images are generated (n > 1), an index will be appended (e.g., /path/to/image_1.png)."), ``` ```ts if (effectiveOutput === "file_output") { const fs = await import("fs/promises"); const path = await import("path"); // If multiple images, append index to filename const basePath = effectiveFileOutput!; const responses = []; for (let i = 0; i < images.length; i++) { const img = images[i]; let filePath = basePath; if (images.length > 1) { const parsed = path.parse(basePath); filePath = path.join(parsed.dir, `${parsed.name}_${i + 1}.${img.ext ?? "png"}`); } else { // Ensure correct extension const parsed = path.parse(basePath); filePath = path.join(parsed.dir, `${parsed.name}.${img.ext ?? "png"}`); } await fs.writeFile(filePath, Buffer.from(img.b64, "base64")); responses.push({ type: "text", text: `Image saved to: file://${filePath}` }); } return { content: responses }; } ``` ```ts if (effectiveOutput === "file_output") { if (!effectiveFileOutput) { throw new Error("file_output path is required when output is 'file_output'"); } const basePath = effectiveFileOutput!; const responses = []; for (let i = 0; i < images.length; i++) { ...[truncated 2533 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
SKILL.md:198
Finding

Runtime Installation Instructions Allow Unpinned Third-Party Dependency Retrieval

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
Findings (28)

Known Vulnerable Dependency: form-data==4.0.2 — 2 advisory(ies): CVE-2025-7783 (form-data uses unsafe random function in form-data for choosing boundary); CVE-2026-12143 (form-data: CRLF injection in form-data via unescaped multipart field names and f)

Critical
Category
Supply Chain
Confidence
95% confidence
Finding

form-data 4.0.2 is affected by unsafe boundary generation and CRLF injection via unescaped multipart field names/filenames. In a skill that handles AI/image generation and may upload files or construct multipart requests to external APIs, malformed multipart construction can enable request smuggling/header injection behaviors or weaken request isolation, making this dependency particularly risky.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description is about building presentation decks with slide rendering, navigation, and PDF export. The supplied code does none of that. Its primary purpose is to run an MCP server with two tools: create-image and edit-image, both backed by OpenAI/Azure image APIs. It can also save generated images to disk at absolute paths and load environment variables from an external file at startup. These are materially different capabilities from presentation generation, so this is a clear description-behavior mismatch.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill requires an OPENAI_API_KEY and directs the agent to generate images from slide content, but it does not disclose that presentation text or derived prompts may be sent to an external AI service. If users provide proprietary, personal, or confidential material, that content could be transmitted off-system without informed consent.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The README documents an MCP server for AI image generation and editing, which does not match the declared skill purpose of generating presentations. This capability mismatch is dangerous because it can conceal unexpected tool behavior, expand the attack surface, and mislead reviewers or users into granting access to functions they did not intend to install or trust.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
"args": [
        "<absolute-path-to>/mcp-servers/openai-gpt-image/dist/index.js",
        "--env-file",
        "<absolute-path-to>/.env"
      ]
    }
  }

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · mcp-servers/openai-gpt-image/README.md (reported line 49)May include surrounding context.

md
"args": [
        "<absolute-path-to>/mcp-servers/openai-gpt-image/dist/index.js",
        "--env-file",
        "<absolute-path-to>/.env"
      ]
    }
  }

Known Vulnerable Dependency: @modelcontextprotocol/sdk==1.10.2 — 3 advisory(ies): CVE-2026-25536 (@modelcontextprotocol/sdk has cross-client data leak via shared server/transport); CVE-2026-0621 (Anthropic's MCP TypeScript SDK has a ReDoS vulnerability); CVE-2025-66414 (Model Context Protocol (MCP) TypeScript SDK does not enable DNS rebinding protec)

High
Category
Supply Chain
Confidence
97% confidence
Finding

The lockfile pins @modelcontextprotocol/sdk to 1.10.2, and the reported advisories include cross-client data leakage, ReDoS, and missing DNS rebinding protections. In an MCP server context, these issues are especially relevant because the package is part of the server/transport layer, so exploitation could expose one client's data to another or allow denial-of-service against the service.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: path-to-regexp==8.2.0 — 2 advisory(ies): CVE-2026-4923 (path-to-regexp vulnerable to Regular Expression Denial of Service via multiple w); CVE-2026-4926 (path-to-regexp vulnerable to Denial of Service via sequential optional groups)

High
Category
Supply Chain
Confidence
90% confidence
Finding

path-to-regexp 8.2.0 is reported vulnerable to ReDoS/DoS through crafted route patterns or inputs that trigger excessive backtracking. Since this dependency sits in the routing stack of Express/router, an attacker sending specially crafted requests could tie up server CPU and impair availability of the MCP service.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: @modelcontextprotocol/sdk==1.10.2 — 3 advisory(ies): CVE-2026-25536 (@modelcontextprotocol/sdk has cross-client data leak via shared server/transport); CVE-2026-0621 (Anthropic's MCP TypeScript SDK has a ReDoS vulnerability); CVE-2025-66414 (Model Context Protocol (MCP) TypeScript SDK does not enable DNS rebinding protec)

High
Category
Supply Chain
Confidence
98% confidence
Finding

The package explicitly uses @modelcontextprotocol/sdk version 1.10.2, which is reported as affected by multiple advisories including cross-client data leaks, ReDoS, and lack of DNS rebinding protection. Because this skill provides an MCP server, compromise of the SDK could expose one client's data to another, enable service degradation via crafted input, or weaken network-origin trust assumptions around the server transport.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README states that the skill uses OpenAI GPT Image models and analyzes user-supplied content/reference images, but it does not clearly warn users that prompts, slide content, URLs, and potentially design-reference data may be sent to a third-party service. This creates a real privacy and data-governance risk, especially if users provide confidential documents, internal URLs, or sensitive branding assets.

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 · README.md (reported line 60)May include surrounding context.

}

text

Create a `.env` file with your OpenAI API key:

OPENAI_API_KEY=sk-your-key-here

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 121)May include surrounding context.

alwaysApply: false

@skills/generate-presentation/SKILL.md

text

When you ask Cursor's agent to create a presentation, it will pick up the skill from the rules.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill declares access to environment variables via metadata requirements but does not define an explicit tool scope such as allowed-tools or permissions. That makes the skill's operational boundary unclear and increases the risk that an agent can access sensitive capabilities or secrets without transparent user consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill tells the agent to fetch arbitrary user-provided URLs without any explicit notice that network access will occur. This can cause unintended outbound requests, leak usage patterns or sensitive query parameters to third parties, and pull untrusted remote content into later processing steps.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill instructs the agent to run pip install Pillow if PDF conversion fails, which introduces unaudited package installation during normal execution. Dynamic dependency installation expands supply-chain risk and can execute arbitrary code from packages or altered indexes, especially in automated environments.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The README advertises writing generated or edited images to arbitrary absolute file paths without warning about overwrite, path safety, or filesystem side effects. In an agent/tooling context, this can enable unsafe writes to sensitive locations or accidental clobbering of user files if callers supply untrusted or mistaken paths.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README instructs users to store an API key in a .env file but does not warn them to protect the file or keep it out of version control. This increases the likelihood of credential leakage through repository commits, logs, backups, or insecure sharing, which can lead to unauthorized API use and billing abuse.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The server accepts a CLI-supplied --env-file path and reads arbitrary files into process.env without any allowlist, path restriction, or ownership checks. In an agent or tool-execution context, this can let a caller influence credentials, endpoints, and runtime behavior by pointing the process at attacker-controlled configuration, which is especially risky because this service selects OpenAI vs Azure behavior from environment variables.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The tool allows callers to supply arbitrary absolute output paths and later writes generated content there, with no sandboxing to a dedicated workspace. In an agent setting, this is dangerous because a prompt or remote instruction can cause writes to sensitive files, overwrite existing data, or plant files in locations consumed by other applications.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

When base64 output exceeds 1MB, the tool silently changes behavior and writes image files to disk, defaulting to /tmp or MCP_HF_WORK_DIR if the caller did not request file output. This violates the principle of least surprise and can create unintended persistence of potentially sensitive generated content, especially in shared or multi-tenant environments.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The edit-image path has the same silent fallback: large results are automatically persisted to disk even if the caller requested base64 output. Because edited images may contain user-supplied source material, this can unexpectedly store sensitive or proprietary content on local storage and expose it to other processes or later retrieval.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The README describes generated output files but does not clearly warn that running the skill will create and may overwrite files in the presentation/ directory during regeneration. This can lead to accidental loss of prior work or confusion about filesystem side effects, particularly in shared or important project directories.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: body-parser==2.2.0 — 2 advisory(ies): CVE-2026-12590 (body-parser vulnerable to denial of service when invalid limit value silently di); CVE-2025-13466 (body-parser is vulnerable to denial of service when url encoding is used)

Low
Category
Supply Chain
Confidence
88% confidence
Finding

body-parser 2.2.0 is flagged for denial-of-service conditions involving invalid limit handling and URL-encoded parsing. Because this package is used by Express-based request handling in the dependency tree, malformed requests may be able to consume excessive resources or degrade availability, though the impact is primarily availability rather than confidentiality or integrity.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: qs==6.14.0 — 4 advisory(ies): CVE-2026-82417 (qs: Denial of Service via Attacker Controlled isBuffer); CVE-2025-15284 (qs's arrayLimit bypass in its bracket notation allows DoS via memory exhaustion); CVE-2026-8723 (qs has a remotely triggerable DoS: qs.stringify crashes with TypeError on null/u) +1 more

Low
Category
Supply Chain
Confidence
86% confidence
Finding

qs 6.14.0 has multiple reported denial-of-service issues involving parser behavior and memory/resource exhaustion. Because qs is commonly used for parsing query strings or URL-encoded bodies in web stacks, untrusted request parameters could be used to increase CPU or memory consumption, but the impact remains mostly availability-focused.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · mcp-servers/openai-gpt-image/package.json (reported line 7)May include surrounding context.

json
"main": "index.js",
  "license": "MIT",
  "devDependencies": {
    "@types/node": "^22.15.2",
    "typescript": "^5.8.3"
  },
  "dependencies": {

Static analysis

No suspicious patterns detected.