Back to skill

Security audit

Report Ppt Generator Pro

Security checks for vulnerabilities and agentic risk

Overview

This presentation-generation skill is mostly coherent, but it needs review because it can fetch arbitrary image URLs and embed local image files without strong boundaries.

Review before installing. Use it only with trusted manuscripts and image sources, avoid untrusted remote image URLs, and prefer local images in a dedicated project folder. Ask the publisher to add URL restrictions, local path containment, pinned dependencies, and clearer language/preview scoping.

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

T09 · Insecure Skill Coding Practices

Warning
Location
assets/scripts/html-to-pptx.js:113
Finding
Unrestricted Local Image Paths Can Disclose Local Files<![CDATA[ ## Vulnerability Details **File Location**: `assets/scripts/html-to-pptx.js:113-121, 540-551` **Vulnerability Type**: Unrestricted local file access through attacker-controlled image paths **Risk Level**: Medium ### Vulnerable Code ```javascript function extractImages(slideHtml) { const images = []; const regex = /<img[^>]*src="([^"]+)"[^>]*>/g; let match; while ((match = regex.exec(slideHtml)) !== null) { if (!match[1].includes('cover_bg') && !match[1].includes('end_bg')) { images.push(match[1]); } } return images; } ``` ```javascript function addImages(slide, images, imgBasePath) { const imgX = 5.0, imgY = 1.1, imgW = 4.7, imgH = 4.0; const validImages = images.filter(p => fs.existsSync(p)); if (validImages.length > 0) { if (validImages.length === 1) { slide.addImage({ path: validImages[0], x: imgX, y: imgY, w: imgW, h: imgH, sizing: { type: 'contain', w: imgW, h: imgH } }); ``` ### Technical Analysis The converter extracts image paths directly from input HTML and treats each extracted value as a local filesystem path. The only validation is `fs.existsSync()`, which confirms that the process can access the path but does not establish that access is authorized. The supplied `imgBasePath` is not used to constrain these image paths. Absolute paths, traversal paths, and paths resolving through symbolic links can therefore refer to files outside the intended working directory. If such a file is a supported image, `pptxgenjs` embeds it in the generated presentation. This violates the documented least-privilege expectation that only user-specified files and Skill resources are read. ### Attack Path 1. An attacker supplies or influences the HTML processed by `html-to-pptx.js`. 2. The HTML contains an image reference to a readable local file, for example: ```html <img src="/path/to/sensitive/local/image.png"> ``` 3. `extractImages()` copies the path without canonicalizat ...[truncated 851 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Resolve every local image path to a canonical absolute path before use: ```javascript const allowedRoot = fs.realpathSync(imgBasePath); const candidate = fs.realpathSync(path.resolve(imgBasePath, imagePath)); ``` 2. Verify that the canonical candidate remains inside the approved root: ```javascript const relative = path.relative(allowedRoot, candidate); if (relative.startsWith('..') || path.isAbsolute(relative)) { throw new Error('Image path is outside the approved directory'); } ``` 3. Reject absolute paths unless the user explicitly approves each path. 4. Resolve real paths before validation to prevent symbolic-link escapes. 5. Allow only expected file extensions and verify file signatures rather than trusting extensions. 6. Apply file-size and image-dimension limits before passing content to `pptxgenjs`. 7. Use `imgBasePath` as an actual security boundary rather than only as a source for cover and end backgrounds. 8. Record rejected paths without exposing unnecessary local filesystem details in user-facing error messages. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
references/image-handling.md:207
Finding
Unrestricted Network Image Fetching Enables Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `references/image-handling.md:31-45, 207-232` **Vulnerability Type**: Server-side request forgery through arbitrary image URLs **Risk Level**: Medium ### Vulnerable Code ```javascript function validateImageSource(source) { // Local file if (source.startsWith('/') || source.startsWith('./') || source.startsWith('~')) { return { type: 'local', path: source }; } // Network URL if (source.startsWith('http://') || source.startsWith('https://')) { return { type: 'url', url: source }; } // Base64 if (source.startsWith('data:image')) { return { type: 'base64', data: source }; } return { type: 'unknown' }; } ``` ```javascript async function downloadImage(url) { const response = await fetch(url); const buffer = await response.arrayBuffer(); return Buffer.from(buffer); } // Use in pptxgenjs const imageData = await downloadImage(imageUrl); slide.addImage({ data: imageData.toString('base64'), x: 1, y: 2, w: 4, h: 3 }); ``` ```javascript async function safeAddImage(slide, imageSource, options) { try { if (imageSource.startsWith('http')) { const imageData = await downloadImage(imageSource); slide.addImage({ data: imageData.toString('base64'), ...options }); } else { slide.addImage({ path: imageSource, ...options }); } } catch (error) { console.warn(`Failed to load image: ${imageSource}`); ``` ### Technical Analysis The Skill’s image-handling instructions classify every HTTP or HTTPS string as an acceptable network image and pass it directly to `fetch()`. No destination policy is applied. The documented implementation does not: - Restrict requests to approved public hosts. - Block loopback, link-local, private, multicast, or reserved address ranges. - Prevent access to cloud instance metadata endpoints. - Revalidate redirect destinations. - Enforce HTTPS. - Verify that the response is an imag ...[truncated 1643 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Permit only HTTPS URLs from an explicit allowlist of trusted image hosts. 2. Parse URLs with the platform URL parser; do not validate them with string-prefix checks. 3. Resolve destination hostnames and reject loopback, link-local, private, multicast, unspecified, and reserved IPv4 and IPv6 ranges. 4. Disable redirects or apply the complete destination validation again after every redirect. 5. Block cloud metadata endpoints and equivalent platform-specific metadata hostnames. 6. Set short connection and total-request timeouts using an abort signal. 7. Stream responses with a strict byte limit instead of reading unbounded content through `arrayBuffer()`. 8. Require a successful HTTP status and an approved image media type. 9. Verify image magic bytes and enforce image dimension limits before PPTX processing. 10. Consider downloading through an isolated proxy with restricted egress and no access to internal networks. ]]>

T08 · Insecure Dependencies

Note
Location
assets/scripts/html-to-pptx.js:11
Finding
Unpinned Runtime Dependency Installation Creates Supply-Chain Exposure<![CDATA[ ## Vulnerability Details **File Location**: `assets/scripts/html-to-pptx.js:11` **Vulnerability Type**: Mutable and unreproducible third-party dependency installation **Risk Level**: Low ### Vulnerable Code ```javascript /** * HTML 转 PPTX 转换脚本 * * 用法: node html-to-pptx.js <htmlPath> <outputPath> [imageBasePath] * * 参数: * htmlPath - HTML 文件路径 * outputPath - 输出 PPTX 文件路径 * imageBasePath - 图片基础路径(可选,默认从 HTML 中的路径读取) * * 依赖: npm install pptxgenjs */ ``` The corresponding `package.json` does not declare `pptxgenjs` in a `dependencies` section, and the audited project contains no lockfile. ### Technical Analysis The installation instruction uses an unversioned package name. Running `npm install pptxgenjs` resolves the package and its transitive dependency graph at installation time rather than installing a reviewed, immutable version. Because the dependency is absent from `package.json` and no lockfile or integrity metadata is included, two installations of the same Skill release may execute different third-party code. Any compromised future release, compromised transitive dependency, or malicious lifecycle script introduced upstream would run with the installing user’s privileges. No evidence was found that `pptxgenjs` itself is malicious. The finding concerns the unsafe and mutable dependency-management process. ### Attack Path 1. A user follows the script’s dependency instruction and runs: ```bash npm install pptxgenjs ``` 2. npm resolves the current package release and current transitive dependency graph. 3. Downloaded package lifecycle scripts, if present, execute with the user’s installation privileges. 4. The converter subsequently loads the downloaded package through: ```javascript const PptxGenJS = require('pptxgenjs'); ``` 5. A compromised or unexpectedly changed package version can therefore affect local execution without any change to the audited Skill files. ### Impact Assessment Potential ...[truncated 491 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Declare `pptxgenjs` in `package.json` using an exact reviewed version rather than a floating range. 2. Generate and commit `package-lock.json` with dependency integrity hashes. 3. In automated or production installation workflows, use: ```bash npm ci ``` 4. Review direct and transitive dependencies before updating the lockfile. 5. Run dependency vulnerability and provenance checks in CI. 6. Where operationally possible, install with lifecycle scripts disabled: ```bash npm ci --ignore-scripts ``` 7. Document a controlled update procedure that requires review and testing before dependency versions change. ]]>
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 Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (17)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The code clearly implements a local HTML-to-PPTX converter. It reads an HTML file path and output path from command-line arguments, parses specific slide div structures, extracts headings, paragraphs, lists, simple grid/flow layouts, and embeds existing local images into a generated PPTX. This partially overlaps with the declared presentation-generation purpose, especially PPT creation and image embedding. However, several prominently declared capabilities are absent: there is no style extraction from example images, no AI image generation, and no HTML preview workflow. Also, the input is not a general text manuscript but a preformatted HTML document with expected class names and structure. Therefore the description materially overstates and mischaracterizes the actual functionality.

Ae1

High
Category
analysis-evasion
Content
- `slide.html` - 页面模板
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Vague Triggers

Medium
Confidence
94% confidence
Finding
The manifest description lists triggers such as "create slides" and "make presentation," which are generic phrases a user might say in many ordinary contexts. The description also provides no negative examples or constraints to clarify when the skill should or should not activate, increasing the risk of unintended invocation.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
Most operational instructions, user prompts, and examples in the skill are written exclusively in Chinese, including the expected workflow dialogue. There is no statement that the skill adapts to the user's preferred language or offers opt-in language selection, which may violate language or locale policy requirements.

Context-Inappropriate Capability

Medium
Confidence
83% confidence
Finding
The manifest describes generating presentations, style extraction, image embedding, AI illustrations, and HTML preview before export. While preview itself fits the purpose, explicitly using a local server to host generated HTML adds a network/listening capability that is not declared in the skill's purpose or permissions section, which only discusses local file access and external LLM APIs.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The HTML sets `lang="zh-CN"` and includes multiple fixed Chinese strings such as `目录`, `感谢聆听`, and navigation labels. Per the policy, forcing a specific language/locale without user opt-in is a natural-language policy violation unless the locale restriction is clearly justified.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
This .js file contains natural-language strings exclusively in Chinese in the header comments and later CLI messages, which imposes a specific language on users. The policy for SQP-3 applies to all file types and allows locale constraints only when users are given a choice or the restriction is clearly justified, neither of which is present here.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger list includes generic phrases such as 'create slides', 'make presentation', and 'convert to powerpoint', which can match a wide range of normal user requests and cause this skill to be invoked too broadly. In a skill that can process documents, extract style from images, and export files, over-broad routing increases the chance of unintended activation, unnecessary access to user content, and confusion or interference with more appropriate skills.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The file describes prompt templates for image generation and then provides the prompt structure, examples, and generated template strings almost entirely in Chinese. Because the document does not offer an opt-in language choice or explain that the skill is intentionally China/Chinese-locale specific, it effectively forces a specific language/locale for users.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The documented workflow downloads arbitrary HTTP(S) image URLs with no mention of user consent, allowlisting, or restrictions on internal/private addresses. In a PPT-generation skill, this can cause server-side requests to attacker-controlled or sensitive endpoints, leaking network metadata/IP information and potentially exposing internal resources or confidential document context through external fetches.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The file includes hardcoded Chinese user-facing text such as `[图片加载失败]`, `数据分析`, and other slide content examples, which implies a fixed output language. There is no indication that the user can choose language/locale or that the guide is intentionally limited to a Chinese-only context.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
This markdown file contains user-facing prompt text exclusively in Chinese, which can impose a specific language on users without opt-in. The policy for this category flags language or locale constraints unless the skill offers a choice or clearly documents a justified regional limitation.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The layout-analysis prompt is presented solely in Chinese and does not offer an alternative language or indicate that the skill is region-specific. That creates a natural-language policy issue because it constrains user interaction to one language without documented justification.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
These instructions are natural-language content embedded in the markdown and require Chinese to use as written. Because no opt-in, alternative locale, or justification is provided, this appears to violate the language/locale policy described for SQP-3.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The guide again uses Chinese-only prompt text for a user-facing workflow. Requiring one language throughout the skill content without opt-in or explanation matches the policy-violation criteria for forced language or locale.

Natural-Language Policy Violations

Low
Confidence
82% confidence
Finding
The package description forces a single language presentation for the skill metadata, and there is no indication that users can choose another language or that the skill is intentionally limited to a Chinese-speaking context. This may conflict with organizational language/locale policy when multilingual or user-selectable language behavior is expected.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
This markdown file contains substantive template content, labels, and examples in Chinese throughout the document. Under the language/locale policy, forcing a specific language without user opt-in can be a natural-language policy violation when no alternative language choice or justification is provided.

Static analysis

No suspicious patterns detected.