Back to skill

Security audit

ZM Image2PPT 视觉幻灯片生成

Security checks for vulnerabilities and agentic risk

Overview

This skill appears to generate PPT decks as advertised, but it includes risky optional automation and configuration paths that users should review before installing.

Install only if you trust the publisher and are comfortable with the skill calling configured image/vision providers, writing outputs and caches under your working directory, and installing Python dependencies. Prefer the maintained `scripts/generate_ppt.py` path, avoid `--backend codex` for untrusted slide content, use a virtual environment, and do not use proprietary templates with untrusted relay endpoints.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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)

T01 · Skill Instruction Hijacking

Error
Location
scripts/codex_backend.py:27
Finding

Untrusted Presentation Content Is Passed to a Full-Auto Codex Agent

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/image_generator.py:108
Finding

API-Controlled Image URLs Enable Server-Side Request Forgery and Arbitrary Response Writes

Content
View full analysis
None: from urllib.parse import urlparse parsed = urlparse(url) if parsed.scheme not in ("http", "https"): raise ValueError( f"Refusing to download a non-HTTP(S) URL: {parsed.scheme}" ) print(f"Downloading image host={parsed.netloc} path={parsed.path[:80]}") resp = requests.get( url, stream=True, timeout=REQUEST_TIMEOUT_SECS, ) resp.raise_for_status() ctype = resp.headers.get("content-type", "") if ctype and not ctype.startswith("image/"): print( f"Non-image Content-Type: {ctype} " f"(still attempting to write the response)" ) MAX_BYTES = 50 * 1024 * 1024 written = 0 with open(output_path, "wb") as f: for chunk in resp.iter_content(chunk_size=8192): written += len(chunk) if written > MAX_BYTES: f.close() os.remove(output_path) raise ValueError( f"Download exceeded the {MAX_BYTES}-byte limit" ) f.write(chunk) ``` ```python # Any HTTP link is accepted as the final fallback. m = re.search(r"(https?://[^\s\)]+)", text) if m: return m.group(1) ``` From the legacy root `generate_ppt.py`: ```python urls = re.findall(r'(https?://[^\s\)]+)', content) if urls: return urls[0] ``` ```python elif image_url_or_data.startswith("http"): resp = requests.get(image_url_or_data, timeout=120) resp.raise_for_status() with open(output_path, "wb") as f: f.write(resp.content) ``` ### Techn ...[truncated 1953 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
generate_ppt.py:44
Finding

Legacy Entry Point Implicitly Loads Credentials from Unrelated Parent Directories

Content
View full analysis
bool: """ Find and load .env file from multiple locations. Search priority: 1. Current script directory 2. Parent directories up to project root 3. video_workflow project .env """ search_paths = [ Path(__file__).parent / ".env", Path.home() / ".claude" / "skills" / "gpt-image2-ppt-skills" / ".env", ] for env_path in search_paths: if env_path.exists(): load_dotenv(env_path, override=True) print(f"Loaded environment from: {env_path}") return True load_dotenv(override=True) print( "Warning: No .env file found, " "using system environment variables" ) return False ``` The loaded credentials are subsequently used in authorization headers: ```python self.api_key = os.getenv("OPENAI_API_KEY") ... self.headers = { "Accept": "application/json", "Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json", } ``` ### Technical Analysis Calling `load_dotenv()` without an explicit path can cause `python-dotenv` to search for a `.env` file in the surrounding directory hierarchy. Consequently, running the legacy root entry point from another project may load credentials and endpoint configuration belonging to that project. The use of `override=True` further increases the risk because values discovered in the file can replace pre-existing process environment values. This behavior contradicts the scoped credential-loading guarantee documented in `SKILL.md`, which states that the Skill does not recursively inspect project directories for `.env` files. The newer `scripts/generate_ppt.py` implementation follows that policy, but the duplicate root entry point ...[truncated 1185 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Installer Uses Open-Ended Dependency Versions in the Active Python Environment

Content
View full analysis
=2.31 python-dotenv>=1.0 python-pptx>=1.0 jsonschema>=4.0 pymupdf>=1.24 ``` From `install_as_skill.sh`: ```bash print_info "Installing Python dependencies..." if command_exists pip3; then pip3 install -q -r "$SKILL_DIR/requirements.txt" else pip install -q -r "$SKILL_DIR/requirements.txt" fi print_success "Dependencies installed" ``` ### Technical Analysis All dependencies use open-ended minimum-version constraints. The installer therefore accepts any future release available from the configured package index without a reviewed upper bound or integrity hash. The installation script invokes whichever `pip3` or `pip` executable is active and does not create a virtual environment. This can install or upgrade packages in the user's active Python environment, interfere with unrelated applications, and execute package installation hooks with the user's privileges. No evidence of a deliberately malicious or typosquatted dependency was found. The vulnerability is the uncontrolled dependency-resolution and installation process. ### Attack Path 1. The user executes `install_as_skill.sh`. 2. The script invokes the active `pip` against an external package index. 3. Dependency resolution selects versions available at installation time rather than a reviewed, reproducible set. 4. Package wheels, source distributions, or build dependencies are downloaded. 5. Installation or build code runs with the permissions of the invoking user. 6. A compromised future release, package-index compromise, or incompatible update can affect the Skill and the active Python environment. ### Impact Assessment Potential impact includes: - Execution of compromised package installation cod ...[truncated 468 chars]
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (125)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The template-analysis flow uploads locally supplied template images to a vision API and caches analysis results on disk, but this data-handling behavior is broader than the simple generation purpose suggests. If users provide proprietary slide templates, this can lead to unintended disclosure of confidential design or business content to third-party services.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The template-analysis flow uploads locally supplied template images to a vision API and caches analysis results on disk, but this data-handling behavior is broader than the simple generation purpose suggests. If users provide proprietary slide templates, this can lead to unintended disclosure of confidential design or business content to third-party services.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The template-analysis flow uploads locally supplied template images to a vision API and caches analysis results on disk, but this data-handling behavior is broader than the simple generation purpose suggests. If users provide proprietary slide templates, this can lead to unintended disclosure of confidential design or business content to third-party services.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The template-analysis flow uploads locally supplied template images to a vision API and caches analysis results on disk, but this data-handling behavior is broader than the simple generation purpose suggests. If users provide proprietary slide templates, this can lead to unintended disclosure of confidential design or business content to third-party services.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The template-analysis flow uploads locally supplied template images to a vision API and caches analysis results on disk, but this data-handling behavior is broader than the simple generation purpose suggests. If users provide proprietary slide templates, this can lead to unintended disclosure of confidential design or business content to third-party services.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The template-analysis flow uploads locally supplied template images to a vision API and caches analysis results on disk, but this data-handling behavior is broader than the simple generation purpose suggests. If users provide proprietary slide templates, this can lead to unintended disclosure of confidential design or business content to third-party services.

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

md
default_prompt: "Make me a 5-slide deck about [topic] using gpt-image2-ppt; pick a fitting style from styles/."

# Trust surface (what the user agrees to when installing this skill):
#   - Reads scoped .env files only (skill dir, ~/.claude/skills/.../, ~/skills/.../)
#     and never walks parent project directories.
#   - Hits exactly the OPENAI_BASE_URL endpoint you set, plus optional
#     VISION_BASE_URL endpoint you set (template-clone mode only).

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

md
default_prompt: "Make me a 5-slide deck about [topic] using gpt-image2-ppt; pick a fitting style from styles/."

# Trust surface (what the user agrees to when installing this skill):
#   - Reads scoped .env files only (skill dir, ~/.claude/skills/.../, ~/skills/.../)
#     and never walks parent project directories.
#   - Hits exactly the OPENAI_BASE_URL endpoint you set, plus optional
#     VISION_BASE_URL endpoint you set (template-clone mode only).

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

md
default_prompt: "Make me a 5-slide deck about [topic] using gpt-image2-ppt; pick a fitting style from styles/."

# Trust surface (what the user agrees to when installing this skill):
#   - Reads scoped .env files only (skill dir, ~/.claude/skills/.../, ~/skills/.../)
#     and never walks parent project directories.
#   - Hits exactly the OPENAI_BASE_URL endpoint you set, plus optional
#     VISION_BASE_URL endpoint you set (template-clone mode only).

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 · agents/openclaw.yaml (reported line 7)May include surrounding context.

yaml
default_prompt: "Make me a 5-slide deck about [topic] using gpt-image2-ppt; pick a fitting style from styles/."

# Trust surface (what the user agrees to when installing this skill):
#   - Reads scoped .env files only (skill dir, ~/.claude/skills/.../, ~/skills/.../)
#     and never walks parent project directories.
#   - Hits exactly the OPENAI_BASE_URL endpoint you set, plus optional
#     VISION_BASE_URL endpoint you set (template-clone mode only).

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

md
default_prompt: "Make me a 5-slide deck about [topic] using gpt-image2-ppt; pick a fitting style from styles/."

# Trust surface (what the user agrees to when installing this skill):
#   - Reads scoped .env files only (skill dir, ~/.claude/skills/.../, ~/skills/.../)
#     and never walks parent project directories.
#   - Hits exactly the OPENAI_BASE_URL endpoint you set, plus optional
#     VISION_BASE_URL endpoint you set (template-clone mode only).

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 · docs/install.md (reported line 46)May include surrounding context.

md
default_prompt: "Make me a 5-slide deck about [topic] using gpt-image2-ppt; pick a fitting style from styles/."

# Trust surface (what the user agrees to when installing this skill):
#   - Reads scoped .env files only (skill dir, ~/.claude/skills/.../, ~/skills/.../)
#     and never walks parent project directories.
#   - Hits exactly the OPENAI_BASE_URL endpoint you set, plus optional
#     VISION_BASE_URL endpoint you set (template-clone mode only).

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 · generate_ppt.py (reported line 44)May include surrounding context.

python
default_prompt: "Make me a 5-slide deck about [topic] using gpt-image2-ppt; pick a fitting style from styles/."

# Trust surface (what the user agrees to when installing this skill):
#   - Reads scoped .env files only (skill dir, ~/.claude/skills/.../, ~/skills/.../)
#     and never walks parent project directories.
#   - Hits exactly the OPENAI_BASE_URL endpoint you set, plus optional
#     VISION_BASE_URL endpoint you set (template-clone mode only).

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 · generate_ppt.py (reported line 49)May include surrounding context.

python
default_prompt: "Make me a 5-slide deck about [topic] using gpt-image2-ppt; pick a fitting style from styles/."

# Trust surface (what the user agrees to when installing this skill):
#   - Reads scoped .env files only (skill dir, ~/.claude/skills/.../, ~/skills/.../)
#     and never walks parent project directories.
#   - Hits exactly the OPENAI_BASE_URL endpoint you set, plus optional
#     VISION_BASE_URL endpoint you set (template-clone mode only).

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 · generate_ppt.py (reported line 63)May include surrounding context.

python
default_prompt: "Make me a 5-slide deck about [topic] using gpt-image2-ppt; pick a fitting style from styles/."

# Trust surface (what the user agrees to when installing this skill):
#   - Reads scoped .env files only (skill dir, ~/.claude/skills/.../, ~/skills/.../)
#     and never walks parent project directories.
#   - Hits exactly the OPENAI_BASE_URL endpoint you set, plus optional
#     VISION_BASE_URL endpoint you set (template-clone mode only).

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 · generate_ppt.py (reported line 196)May include surrounding context.

python
default_prompt: "Make me a 5-slide deck about [topic] using gpt-image2-ppt; pick a fitting style from styles/."

# Trust surface (what the user agrees to when installing this skill):
#   - Reads scoped .env files only (skill dir, ~/.claude/skills/.../, ~/skills/.../)
#     and never walks parent project directories.
#   - Hits exactly the OPENAI_BASE_URL endpoint you set, plus optional
#     VISION_BASE_URL endpoint you set (template-clone mode only).

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 · install_as_skill.sh (reported line 125)May include surrounding context.

sh
default_prompt: "Make me a 5-slide deck about [topic] using gpt-image2-ppt; pick a fitting style from styles/."

# Trust surface (what the user agrees to when installing this skill):
#   - Reads scoped .env files only (skill dir, ~/.claude/skills/.../, ~/skills/.../)
#     and never walks parent project directories.
#   - Hits exactly the OPENAI_BASE_URL endpoint you set, plus optional
#     VISION_BASE_URL endpoint you set (template-clone mode only).

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 · install_as_skill.sh (reported line 137)May include surrounding context.

sh
default_prompt: "Make me a 5-slide deck about [topic] using gpt-image2-ppt; pick a fitting style from styles/."

# Trust surface (what the user agrees to when installing this skill):
#   - Reads scoped .env files only (skill dir, ~/.claude/skills/.../, ~/skills/.../)
#     and never walks parent project directories.
#   - Hits exactly the OPENAI_BASE_URL endpoint you set, plus optional
#     VISION_BASE_URL endpoint you set (template-clone mode only).

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 · install_as_skill.sh (reported line 186)May include surrounding context.

sh
default_prompt: "Make me a 5-slide deck about [topic] using gpt-image2-ppt; pick a fitting style from styles/."

# Trust surface (what the user agrees to when installing this skill):
#   - Reads scoped .env files only (skill dir, ~/.claude/skills/.../, ~/skills/.../)
#     and never walks parent project directories.
#   - Hits exactly the OPENAI_BASE_URL endpoint you set, plus optional
#     VISION_BASE_URL endpoint you set (template-clone mode only).

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 · scripts/generate_ppt.py (reported line 37)May include surrounding context.

python
default_prompt: "Make me a 5-slide deck about [topic] using gpt-image2-ppt; pick a fitting style from styles/."

# Trust surface (what the user agrees to when installing this skill):
#   - Reads scoped .env files only (skill dir, ~/.claude/skills/.../, ~/skills/.../)
#     and never walks parent project directories.
#   - Hits exactly the OPENAI_BASE_URL endpoint you set, plus optional
#     VISION_BASE_URL endpoint you set (template-clone mode only).

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 · scripts/generate_ppt.py (reported line 41)May include surrounding context.

python
default_prompt: "Make me a 5-slide deck about [topic] using gpt-image2-ppt; pick a fitting style from styles/."

# Trust surface (what the user agrees to when installing this skill):
#   - Reads scoped .env files only (skill dir, ~/.claude/skills/.../, ~/skills/.../)
#     and never walks parent project directories.
#   - Hits exactly the OPENAI_BASE_URL endpoint you set, plus optional
#     VISION_BASE_URL endpoint you set (template-clone mode only).

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 · scripts/generate_ppt.py (reported line 42)May include surrounding context.

python
default_prompt: "Make me a 5-slide deck about [topic] using gpt-image2-ppt; pick a fitting style from styles/."

# Trust surface (what the user agrees to when installing this skill):
#   - Reads scoped .env files only (skill dir, ~/.claude/skills/.../, ~/skills/.../)
#     and never walks parent project directories.
#   - Hits exactly the OPENAI_BASE_URL endpoint you set, plus optional
#     VISION_BASE_URL endpoint you set (template-clone mode only).

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 · scripts/generate_ppt.py (reported line 43)May include surrounding context.

python
default_prompt: "Make me a 5-slide deck about [topic] using gpt-image2-ppt; pick a fitting style from styles/."

# Trust surface (what the user agrees to when installing this skill):
#   - Reads scoped .env files only (skill dir, ~/.claude/skills/.../, ~/skills/.../)
#     and never walks parent project directories.
#   - Hits exactly the OPENAI_BASE_URL endpoint you set, plus optional
#     VISION_BASE_URL endpoint you set (template-clone mode only).

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 · scripts/generate_ppt.py (reported line 44)May include surrounding context.

python
default_prompt: "Make me a 5-slide deck about [topic] using gpt-image2-ppt; pick a fitting style from styles/."

# Trust surface (what the user agrees to when installing this skill):
#   - Reads scoped .env files only (skill dir, ~/.claude/skills/.../, ~/skills/.../)
#     and never walks parent project directories.
#   - Hits exactly the OPENAI_BASE_URL endpoint you set, plus optional
#     VISION_BASE_URL endpoint you set (template-clone mode only).

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 · scripts/generate_ppt.py (reported line 68)May include surrounding context.

python
default_prompt: "Make me a 5-slide deck about [topic] using gpt-image2-ppt; pick a fitting style from styles/."

# Trust surface (what the user agrees to when installing this skill):
#   - Reads scoped .env files only (skill dir, ~/.claude/skills/.../, ~/skills/.../)
#     and never walks parent project directories.
#   - Hits exactly the OPENAI_BASE_URL endpoint you set, plus optional
#     VISION_BASE_URL endpoint you set (template-clone mode only).