Back to skill

Security audit

custom-ai-pptx-generator | 可定制化AI 演示文稿(PPT)生成器 ·

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a coherent PowerPoint-generation workflow, but some bundled scripts can silently overwrite local output files despite explicit no-overwrite claims.

Install only if you are comfortable with a skill that reads your presentation materials, may use image-generation services for previews, and runs local PowerPoint/Python helper scripts. Use a dedicated empty output folder, avoid sensitive materials with cloud image tools unless approved, and review or patch the overwrite behavior before using cutout.py or export_png_template.ps1 on important files.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/cutout.py:95
Finding
Silent Overwrite of Existing Processed Image Assets<![CDATA[ ## Vulnerability Details **File Location**: `scripts/cutout.py`, lines 95–103 **Vulnerability Type**: Unsafe file handling and silent artifact overwrite **Risk Level**: Medium ### Complete Code Snippet ```python def safe_save_path(path): """Return a non-existing path: bump _v2/_v3... suffix instead of overwriting.""" base, ext = os.path.splitext(path) cand, n = path, 1 while os.path.exists(cand): n += 1 cand = "%s_v%d%s" % (base, n, ext) return cand ``` The vulnerable output operation does not use that helper: ```python rgba = Image.fromarray( np.dstack([ np.clip(a, 0, 255).astype(np.uint8), (alpha * 255).astype(np.uint8) ]), "RGBA" ) bbox = rgba.getchannel("A").point(lambda v: 255 if v > 8 else 0).getbbox() if bbox: rgba = rgba.crop(bbox) rgba.save(os.path.join(OUT, name + ".png")) ``` The associated comments claim that existing outputs are protected: ```python # Input/output dirs: override with env vars CUTOUT_IN / CUTOUT_OUT. # Defaults are relative to this script; existing outputs are never overwritten # (auto version bump via safe_save_path below). ``` ### Technical Analysis The script processes ten fixed asset names and saves each result under a deterministic filename, such as `hero.png`, `flow.png`, or `robot.png`. Pillow's `Image.save()` replaces an existing file when the destination path already exists. Although the script provides `safe_save_path()`, the helper is not applied to the processed asset outputs. It is only used later for the verification sheet. This contradicts both the comments in this script and the Skill's documented guarantee that existing artifacts are never silently overwritten. The output directory is controlled through the `CUTOUT_OUT` environment variable. Consequently, a caller can direct the script to any writable directory. Files matching one of the ten fixed output names will then be replaced without confirmation or backup. This is a destr ...[truncated 1437 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Apply `safe_save_path()` to every processed asset before saving: ```python output_path = safe_save_path(os.path.join(OUT, name + ".png")) rgba.save(output_path) ``` Because later code currently reopens fixed filenames, retain the resolved output paths: ```python generated = {} def process(name): # Existing processing logic... output_path = safe_save_path(os.path.join(OUT, name + ".png")) rgba.save(output_path) generated[name] = output_path return output_path for n in NAMES: process(n) tiles = [ (name, Image.open(generated[name]).convert("RGBA")) for name in NAMES ] ``` Additional hardening should include: 1. Resolve `CUTOUT_OUT` to an absolute path and display it before processing. 2. Add an explicit opt-in overwrite flag if replacement is ever required. 3. Refuse to overwrite by default using exclusive file creation or a pre-save existence check. 4. Create a unique per-run output directory to keep each processing run isolated. 5. Add automated tests verifying that two consecutive runs preserve the first run's files. 6. Update documentation so its non-overwrite guarantee matches actual behavior. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/export_png_template.ps1:15
Finding
Caller-Supplied Export Directory Allows Silent PNG Replacement and Stale Output Mixing<![CDATA[ ## Vulnerability Details **File Location**: `scripts/export_png_template.ps1`, lines 15–33 **Vulnerability Type**: Unsafe output-directory reuse and silent artifact overwrite **Risk Level**: Medium ### Complete Code Snippet ```powershell param( [Parameter(Mandatory = $true)][string]$PptxPath, [string]$OutDir = "" ) $ErrorActionPreference = 'Stop' if (-not (Test-Path -LiteralPath $PptxPath)) { throw "PptxPath not found: $PptxPath" } if ($OutDir -eq "") { $stamp = Get-Date -Format 'yyyyMMdd_HHmmss' $OutDir = Join-Path ` (Split-Path -Parent (Resolve-Path -LiteralPath $PptxPath).Path) ` ("png_" + $stamp) } $OutDir = [System.IO.Path]::GetFullPath($OutDir) if (-not (Test-Path -LiteralPath $OutDir)) { New-Item -ItemType Directory -Path $OutDir -Force | Out-Null } $app = $null $pres = $null $count = 0 try { $app = New-Object -ComObject PowerPoint.Application $pres = $app.Presentations.Open( (Resolve-Path -LiteralPath $PptxPath).Path, $true, $false, $false ) $i = 0 foreach ($slide in $pres.Slides) { $i++ $png = Join-Path $OutDir ("slide_" + $i + ".png") $slide.Export($png, 'PNG', 1920, 1080) Write-Output ("exported " + $png) } $count = $i } finally { if ($null -ne $pres) { $pres.Close() } if ($null -ne $app) { $app.Quit() } } ``` The script also makes the following safety claim: ```powershell # Safety rules (ClawHub T09 remediation): # 1. NEVER deletes existing files. Output goes to a run-specific directory. ``` ### Technical Analysis When `OutDir` is omitted, the script constructs a timestamp-based directory. However, callers may supply an existing directory through `-OutDir`. In that case, the script uses the supplied directory directly rather than creating a unique run-specific child directory. Each slide is exported under a deterministic filename such as `slide_1.png` or `slide_2.png`. No check is made to d ...[truncated 2035 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Always create a unique run-specific child directory, even when the caller supplies a base output directory: ```powershell if ($OutDir -eq "") { $baseDir = Split-Path -Parent (Resolve-Path -LiteralPath $PptxPath).Path } else { $baseDir = [System.IO.Path]::GetFullPath($OutDir) } if (-not (Test-Path -LiteralPath $baseDir)) { New-Item -ItemType Directory -Path $baseDir | Out-Null } $stamp = Get-Date -Format 'yyyyMMdd_HHmmss_ffff' $OutDir = Join-Path $baseDir ("png_" + $stamp) New-Item -ItemType Directory -Path $OutDir | Out-Null ``` Also reject any unexpected collision before exporting: ```powershell $png = Join-Path $OutDir ("slide_" + $i + ".png") if (Test-Path -LiteralPath $png) { throw "Refusing to overwrite existing export: $png" } $slide.Export($png, 'PNG', 1920, 1080) ``` Additional hardening should include: 1. Treat `-OutDir` as a base directory rather than the final run directory. 2. Use sub-second timestamp precision or a random identifier to prevent same-second collisions. 3. Refuse to export into a non-empty final directory. 4. Write a manifest containing the source PPTX path, source hash, export time, and exact slide count. 5. Validate after export that the directory contains exactly the expected slide files. 6. Add regression tests for existing output directories, filename collisions, and decks with fewer slides than previous runs. 7. Amend the safety comments if direct directory reuse remains supported. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (21)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The declared purpose describes a full AI-driven presentation creation workflow from user content through design planning, confirmation stages, native PPTX rebuilding, and COM-based visual QA. The supplied code does not implement that workflow. Instead, it is a narrow internal test utility: it creates several standalone PPTX files, each demonstrating a specific PowerPoint feature (alpha fill, gradient, shadow, connector, bullets, special shapes, picture, rotation, text alignment) for troubleshooting or bisecting compatibility issues. While it does generate PPTX files, that is only a superficial overlap. Its primary purpose is materially different from the declared end-user AI PPT generator, and it includes an undeclared diagnostic/testing capability.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared skill is a full presentation-generation pipeline centered on turning user-provided content into editable PowerPoint decks with multiple design-confirmation stages. The supplied code does none of that. It is a standalone asset-cleanup utility for PNG images: it estimates background color, removes a green-screen-like background, removes a stamped watermark area, fixes edge fringes, trims transparency, and outputs cleaned images plus a verification sheet. This is a materially different primary purpose and introduces an undeclared capability (watermark removal / image cleanup) unrelated to the declared AI PPTX generation behavior.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description is for an end-to-end AI-driven PPT creation skill that produces editable PowerPoint decks after content analysis and multiple design confirmation steps. The supplied code does none of that. It is a simple image-analysis script using PIL to open specific PNG files in a local directory, compute quantized top colors, sample colors at fixed positions, and print image metadata. While color extraction could theoretically support slide design work, this snippet by itself is not a supporting implementation of PPT generation; its primary behavior is materially different and much narrower than the declared skill purpose.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description presents a full AI-assisted PowerPoint creation workflow that transforms arbitrary user content into an editable presentation through several review stages. The supplied code does use python-pptx and does generate an editable PPTX, but its actual purpose is much narrower and materially different: it draws several predefined sync icon candidates on a single slide for visual comparison and saves the result. There is no evidence of content parsing, design-intent generation, user confirmation loops, storyboard creation, prototype approval, native rebuild from analyzed content, or rendering/QA steps. This is therefore a clear description-versus-behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description promises a full AI-assisted PPTX generation workflow driven by user content, with multiple approval stages and final editable slide decks. The provided code does something much narrower and unrelated: it programmatically draws predefined shapes/icons on a single slide for what appears to be icon synchronization/testing, then saves a test PPTX. While it does use python-pptx and outputs a native editable PowerPoint file, that is only a small supporting detail and not enough to match the declared primary purpose. The actual behavior is materially different from the described end-to-end AI presentation generator.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The README says the skill should auto-trigger whenever a user asks to make a PPT and wants an editable PowerPoint, which is a broad class of common requests. In an agent environment, overly broad trigger conditions can cause unintended invocation, exposing user content and files to a workflow that may process attachments, call external tooling, or take actions the user did not explicitly select.

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The trigger scope is very broad, causing the skill to activate on common presentation-related requests without clear exclusions. In an agent ecosystem, overbroad routing can expose user content to unnecessary local-file, environment, or script-oriented processing and can displace safer, narrower skills, increasing the chance of misuse or unintended actions.

Context-Inappropriate Capability

Medium
Confidence
84% confidence
Finding
The workflow explicitly supports external image-generation services and references cloud credential configuration, expanding the trust boundary beyond a local PPTX-building skill. This creates data exposure risk because user content, slide text, or design material may be sent to third-party services, potentially conflicting with user expectations from the skill description.

Context-Inappropriate Capability

Medium
Confidence
92% confidence
Finding
The document includes guidance to terminate PowerPoint processes as part of recovery, which is host process control beyond the minimum needed for PPT generation. Even though later text narrows this and warns against indiscriminate termination, normalizing process-kill behavior in a skill can still lead to accidental disruption or loss of unrelated user work if implemented incorrectly.

Ssd 3

Medium
Confidence
90% confidence
Finding
The instruction to retain intermediate user iterations in the skill documentation introduces a data-retention risk, because drafts, prompts, emails, and other user-provided content may be preserved beyond the task's operational need. Such retained natural-language artifacts can later leak sensitive business information, personal data, or proprietary materials through reuse, packaging, or broader access to the skill bundle.

Natural-Language Policy Violations

Low
Confidence
68% confidence
Finding
The document presents core instructions and labels in both Chinese and English, but does not state whether the skill adapts to the user's preferred language or locale. If the skill behavior or outputs follow a fixed language convention without opt-in, that can create a language-policy concern.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
The skill title and the surrounding instructions are presented in Chinese-heavy wording, while other sections mix English terminology, but the document does not state that the user may choose their preferred language for interaction or deliverables. This can create a locale or language-policy issue because the skill appears to assume a default language style without explicit opt-in.

Natural-Language Policy Violations

Low
Confidence
86% confidence
Finding
The file includes fixed English text such as "SSC Automation Project," "Next Steps," "Thank You," and roadmap labels like "Identify" and "Automate" inside an otherwise Chinese-language prompt set. This imposes a language choice in the generated output without user opt-in or justification, which matches the language/locale policy concern.

Missing User Warnings

Low
Confidence
89% confidence
Finding
The prompt package instructs users to store generated image assets in a specific absolute local Windows path that includes a user profile name. Hardcoded local paths can leak environment details, encourage unsafe handling of potentially sensitive presentation materials, and reduce portability across systems. In this skill context, the content is about generating editable PPTs from user-supplied business materials, so those images may contain internal or confidential information and should not be casually stored without data-handling guidance.

Missing User Warnings

Low
Confidence
79% confidence
Finding
The file references sensitive credential variables without adjacent handling guidance, which can encourage unsafe secret use in logs, prompts, or configuration files. While merely naming environment variables is not inherently dangerous, the absence of explicit safeguards in an operational workflow raises the chance of accidental credential disclosure.

Missing User Warnings

Low
Confidence
76% confidence
Finding
Process-termination behavior is mentioned in the workflow area without an upfront high-visibility warning, which can cause downstream implementations to understate the operational risk. In practice this can lead to user disruption or unsaved-work loss if developers copy the recovery pattern without the later nuance and safeguards.

Missing User Warnings

Low
Confidence
88% confidence
Finding
The script saves processed PNGs directly to the output path with `rgba.save(os.path.join(OUT, name + ".png"))`. Although comments mention that existing outputs are never overwritten, that protection is only used later for the verification sheet and not for these per-asset writes, and there is no user-facing warning or confirmation before replacing files in the output directory.

Intent-Code Divergence

Low
Confidence
76% confidence
Finding
The comment says 'Never overwrite existing artifacts,' which suggests a single-save safety guarantee. However, the script always creates output directories and saves the presentation twice to two different paths, producing additional artifacts rather than simply avoiding overwrite; this does not match the plain reading of the comment. The mismatch is documentation-level rather than a security-sensitive behavior change.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
The file sets `FONT = "微软雅黑"`, which forces a specific locale-associated font throughout generated slides. Under the stated policy, forcing a language/locale-specific presentation choice without user opt-in can be a natural-language policy concern when no fallback or user selection is provided.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
The code hard-codes the typeface "微软雅黑" for all latin, East Asian, and complex-script text runs. This imposes a specific locale-dependent font choice without any user opt-in or documented justification, which can violate language/locale policy expectations.

Static analysis

No suspicious patterns detected.