Back to skill

Security audit

ppt-mcp-server

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says, but it gives the AI broad unsandboxed Python execution to make PowerPoint files.

Install only in a tightly sandboxed environment with no secrets, no broad workspace access, and preferably no network access. Treat every generated PPT request as code execution, review or confirm code before running it, and pin dependencies before deployment.

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

T09 · Insecure Skill Coding Practices

Error
Location
server.py:40
Finding

Unrestricted Execution of Model-Generated Python Code

Content
View full analysis

Vulnerability Details

File Location: server.py:40-70
Supporting Instruction Location: SKILL.md:27-33, 109-116, 151-153
Vulnerability Type: Arbitrary code execution without isolation
Risk Level: High

Vulnerable Code:

python
exec_globals = {
    "__builtins__": __builtins__,
    "__name__": "__main__",
    "__file__": os.path.join(OUTPUT_DIR, "temp_script.py"),
}

original_cwd = os.getcwd()
os.chdir(OUTPUT_DIR)

exec(processed_code, exec_globals)

The Skill instructions also require generated code to be executed automatically:

text
- Generate complete, executable Python code using python-pptx
- After generating the code, invoke execute_pptx_code to execute it

Technical Analysis

The execute_pptx_code MCP tool accepts a caller-controlled python_code string and passes it directly to Python's in-process exec function. The execution globals explicitly expose the complete __builtins__ object. Consequently, executed code can import modules, invoke subprocesses, inspect environment variables, read or modify files, open network connections, terminate the process, and mutate MCP server state.

_preprocess_code only uses regular expressions to rewrite some literal prs.save() and Presentation() calls. This is not a security boundary. Code can bypass those rewrites through aliases, variables, dynamic expressions, direct filesystem APIs, imported modules, or operating-system commands. Changing the current working directory to output similarly does not restrict access to absolute paths or parent directories.

The code runs inside the MCP server process rather than an isolated worker. It therefore inherits all filesystem, network, credential, and operating-system permissions granted to that process. Content supplied to an AI could also indirectly influence generated code, making prompt or document content a potential entry point.

Attack Path

  1. An attacker ...[truncated 1742 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove general-purpose Python execution from the MCP interface. Replace python_code with a structured presentation specification containing only required concepts such as slides, text, shapes, layouts, colors, and output names.
  2. Implement presentation construction in trusted server code using python-pptx. Validate all structured fields against strict schemas, size limits, and enumerated operations.
  3. If arbitrary execution is an unavoidable product requirement, execute each request in a disposable container or virtual machine rather than the MCP process.
  4. Configure the isolation boundary with:
    • A dedicated unprivileged user.
    • No host credentials or environment secrets.
    • Network access disabled by default.
    • A read-only root filesystem.
    • Explicit, narrowly scoped input and output mounts.
    • CPU, memory, process-count, file-size, and execution-time limits.
    • Mandatory termination and cleanup after every invocation.
    • A restrictive seccomp/AppArmor/SELinux policy where supported.
  5. Validate output filenames independently and reject path separators, traversal sequences, control characters, and unexpected extensions.
  6. Do not treat restricted globals, Python AST filtering, regular-expression rewriting, or removal of selected builtins as a sufficient sandbox; Python code must be isolated at the operating-system boundary.
  7. Require explicit user confirmation before executing generated code until the general-purpose execution interface is removed.
  8. Log execution metadata without recording secrets, and monitor repeated failures, abnormal resource use, and unexpected output files.

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Unbounded Third-Party Dependency Versions

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1-2
Vulnerability Type: Unpinned dependency resolution and supply-chain exposure
Risk Level: Medium

Vulnerable Code:

text
mcp>=1.6.0
python-pptx>=0.6.21

Technical Analysis

Both dependencies use lower-bound-only version constraints. A new installation can therefore resolve to any future release satisfying the minimum version, including versions that were never reviewed or tested with this project. Transitive dependency versions are also not locked, and no package hashes are supplied.

This makes installations non-reproducible and permits runtime behavior to change without any modification to the audited repository. If a future direct or transitive release is compromised, malicious installation or runtime code could be introduced through an otherwise normal pip install -r requirements.txt command.

The reviewed package names do not show evidence of typographical impersonation, and the repository does not reference an untrusted custom package index. The confirmed issue is the absence of exact reviewed versions and integrity hashes, not evidence that the currently named packages are malicious.

Attack Path

  1. A user installs the project using pip install -r requirements.txt, as documented.
  2. The package resolver selects the newest available versions satisfying the lower bounds.
  3. Those versions or their transitive dependencies may differ from the versions originally tested by the author.
  4. If a selected release is compromised or contains a newly introduced vulnerability, its code is installed into the MCP server environment.
  5. The dependency code executes during installation, import, or normal server operation with the privileges of the installing or server account.

Impact Assessment

The exact impact depends on the behavior of the unexpectedly resolved package. A compromised dependency could obtain the installer o ...[truncated 289 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin every direct dependency to an exact version that has been tested and reviewed.
  2. Generate a lock file that records all transitive dependencies.
  3. Require cryptographic hashes during installation, for example through a hash-locked requirements file and pip --require-hashes.
  4. Build dependencies through a controlled update process that includes vulnerability scanning, release-note review, compatibility testing, and security review.
  5. Use a trusted package index and prevent dependency resolution from unapproved indexes.
  6. Run installation in a dedicated virtual environment or build container without access to production credentials.
  7. Automate dependency update proposals while requiring review before merging or deployment.
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (14)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill description does not clearly warn users that it will automatically generate and execute Python code and write files to disk. In context, the embedded system prompt explicitly requires code execution and retry on failure, so lack of disclosure meaningfully increases the risk of users consenting to behavior they do not understand.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The tool invites users or agents to provide executable Python code but does not present an explicit warning that this can run arbitrary code with filesystem side effects. In an agent skill context, lack of disclosure is dangerous because users may reasonably assume the tool only manipulates PPT content, while it can actually execute hostile payloads generated by the model or embedded in prompts.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The implementation allows arbitrary Python execution, not just PPT-specific operations, so an attacker can read/write files, exfiltrate data, install persistence, or run shell commands. Because this is an MCP skill likely exposed to agent-driven inputs, the context makes it especially dangerous: any compromised prompt chain or malicious user request can turn the server into a general-purpose code execution primitive.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code comments claim a 'safe execution environment,' but exec_globals exposes full builtins, which is not a meaningful sandbox and can mislead operators into trusting unsafe behavior. This mismatch increases operational risk because developers or users may deploy the skill in sensitive environments under a false assumption of confinement.

Content

No source excerpt is available for this finding.

exec() call detected

High
Category
Dangerous Code Execution
Confidence
99% confidence
Finding

The tool executes attacker- or model-controlled Python via exec() with unrestricted builtins, so the code can perform arbitrary OS, filesystem, network, and subprocess actions rather than just generate PowerPoint files. In this skill context, the danger is heightened because the core feature explicitly accepts generated code from an LLM, making prompt injection or malicious code generation directly exploitable.

Content

Scanner excerpt · server.py (reported line 66)May include surrounding context.

python
os.chdir(OUTPUT_DIR)

        # --- 3. 执行代码 ---
        exec(processed_code, exec_globals)

        # 恢复工作目录
        os.chdir(original_cwd)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README describes automatic PPT generation but does not clearly warn users that the skill will create and save files as a side effect. Because this skill executes python-pptx code to produce documents, missing disclosure can lead to unexpected file creation, confusion about where outputs are stored, and unsafe use in environments where write actions require explicit consent.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The invocation example is phrased like an ordinary user request rather than an explicitly scoped tool invocation, which increases the chance the skill is triggered during normal conversation without clear user intent. In this skill’s context, that matters because the tool can generate and save files automatically, turning ambiguous language into filesystem side effects.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill exposes code-execution-oriented behavior and references file-related capabilities, but it declares no explicit tool scope or permission boundary. In a skill that instructs the model to generate and execute Python code, missing scope declarations increases the chance of unintended file access or broader tool usage than users expect.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The invocation examples are generic, everyday requests that a user might say in normal conversation, which can cause the skill to trigger without clear intent. Because this skill then generates and executes Python code, accidental activation carries more risk than a typical content-only skill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill’s descriptive text and user-facing documentation/comments are written in Chinese only, which imposes a language choice without any opt-in or stated regional constraint. Under the policy, forcing a specific language or locale without user choice is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

All user-facing natural-language instructions and the example interaction are presented only in Chinese, with no indication that other languages are supported or that Chinese is an intentional locale-specific restriction. This can be interpreted as imposing a language choice on users without offering opt-in or documenting the constraint.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency specifier mcp>=1.6.0 is unpinned, so future installs may resolve to different versions over time, including releases with newly introduced bugs or security issues. In a tool that executes generated code to build PPT files, dependency drift increases supply-chain risk and makes builds non-reproducible.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
mcp>=1.6.0
python-pptx>=0.6.21

Unverifiable Dependency: mcp has 12 known advisory(ies) (CVE-2025-53366 (MCP Python SDK vulnerability in the FastMCP Server causes validation error, lead); CVE-2025-66416 (Model Context Protocol (MCP) Python SDK does not enable DNS rebinding protection); CVE-2026-52870 (MCP Python SDK: Experimental task handlers allow any client to access and cancel) +9 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The manifest includes mcp without an exact version while the package has multiple known security advisories, so there is no way to verify whether deployed installations are affected or safely patched. Given this skill is an MCP-based tool, the mcp package is part of the core trust boundary, making uncertainty around its version more dangerous than a generic library pinning issue.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

The dependency python-pptx>=0.6.21 is also unpinned, allowing installation of any later version, which can introduce unexpected behavior or vulnerable releases. This is a classic supply-chain hygiene issue rather than an immediate exploit, but it weakens reproducibility and controlled patch management.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
mcp>=1.6.0
python-pptx>=0.6.21