Back to skill

Security audit

123

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to be a real PowerPoint generator, but its filename inputs can escape the skill folder and overwrite writable files.

Review before installing. Use only trusted template files, avoid passing absolute or ../ paths, and run it in a restricted workspace because a crafted output filename could overwrite files the process can write. Pin the dependency 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 (2)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/index.py:428
Finding

Caller-Controlled Paths Permit Unauthorized File Read and Write

Content
View full analysis

Vulnerability Details

File Location: src/index.py, lines 428-440
Vulnerability Type: Path traversal and unrestricted filesystem access
Risk Level: High

Vulnerable Code

python
async def handler(input: dict[str, Any], _context: Any) -> dict[str, Any]:
    skill_root = Path(__file__).resolve().parent.parent
    template_file = input.get("template_file") or "PPT_Template.pptx"
    template_path = skill_root / template_file
    if not template_path.exists():
        raise FileNotFoundError(f"Template not found: {template_path}")

    mode = (input.get("mode") or "xml").strip().lower()
    if mode != "xml":
        raise ValueError("Only xml mode is supported")

    title = input.get("title", "Corporate Deck")
    output_filename = input.get("output_filename", "openclaw_generated_xml.pptx")
    output_path = skill_root / output_filename

The resulting paths are subsequently used without confinement checks:

python
prs = Presentation(str(template_path))
...
prs.save(str(output_path))

Technical Analysis

Both template_file and output_filename are controlled by the caller. Joining an untrusted path to skill_root does not ensure that the result remains inside the skill directory:

  • A path containing ../ can traverse outside the intended directory.
  • If the supplied path is absolute, Python's pathlib discards the preceding skill_root.
  • The implementation does not call resolve() and verify that the resolved path is beneath an approved directory.
  • The output path has no extension restriction, overwrite protection, or collision check.

The template input must be a file that python-pptx can successfully parse, which limits arbitrary reading to compatible PowerPoint files. Nevertheless, the caller can select any accessible compatible file outside the skill directory. More critically, the output operation can create or overwrite any file writable by the skil ...[truncated 1415 chars]

Remediation
View remediation

Remediation Suggestions

  1. Define separate, explicit directories for approved templates and generated output.
  2. Reject absolute caller-supplied paths.
  3. Resolve each candidate path and verify that it remains beneath the corresponding approved directory.
  4. Restrict both template and output files to the .pptx extension.
  5. Treat caller input as a filename rather than an unrestricted path when subdirectories are unnecessary.
  6. Refuse to overwrite existing files unless overwrite behavior is explicitly authorized.
  7. Ensure the output path cannot equal the template path.
  8. Run the skill under a dedicated account with minimal filesystem permissions.

Example hardening logic:

python
def confined_pptx_path(base: Path, supplied: str) -> Path:
    if not supplied:
        raise ValueError("A filename is required")

    untrusted = Path(supplied)
    if untrusted.is_absolute():
        raise ValueError("Absolute paths are not allowed")
    if untrusted.suffix.lower() != ".pptx":
        raise ValueError("Only .pptx files are allowed")

    resolved_base = base.resolve()
    candidate = (resolved_base / untrusted).resolve()
    if not candidate.is_relative_to(resolved_base):
        raise ValueError("Path escapes the approved directory")
    return candidate

template_path = confined_pptx_path(template_directory, template_file)
output_path = confined_pptx_path(output_directory, output_filename)

if output_path == template_path:
    raise ValueError("Output path cannot overwrite the template")
if output_path.exists():
    raise FileExistsError(f"Output already exists: {output_path}")

Where atomic output creation is required, write to a securely created temporary file inside the approved output directory and atomically rename it after successful generation.

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Unbounded Third-Party Dependency Reduces Supply-Chain Integrity

Content
View full analysis

Vulnerability Details

File Location: requirements.txt, line 1; installation documented in README.md, lines 20-22
Vulnerability Type: Unpinned third-party dependency
Risk Level: Low

Vulnerable Code

requirements.txt:

text
python-pptx>=0.6.23

README.md:

bash
python3 -m pip install -r requirements.txt

Technical Analysis

The lower-bound-only requirement permits installation of any future python-pptx release that satisfies the minimum version. No lock file or package hashes are supplied.

As a result, two installations performed at different times can resolve to different artifacts. This weakens build reproducibility and makes the effective dependency set dependent on the state and configuration of the package index at installation time.

The reviewed project does not contain evidence that python-pptx itself is malicious. The risk arises from trusting an unconstrained future version or an untrusted package index without artifact verification.

Attack Path

  1. A user follows the documented installation command.
  2. pip queries the configured package index and selects the newest release satisfying python-pptx>=0.6.23.
  3. A compromised upstream release, package-index account, mirror, or installation environment supplies a malicious or otherwise unsafe future artifact.
  4. Because no exact version or hash is enforced, the artifact is accepted.
  5. Malicious package installation or runtime code can execute with the privileges of the user performing installation or running the skill.

This path requires compromise or unsafe configuration of the dependency supply chain; it is not directly exploitable solely through normal skill input.

Impact Assessment

If a malicious dependency artifact is installed, its code can run with the permissions of the installing or runtime account. Potential impact includes access to files, environment variables, process creden ...[truncated 215 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin python-pptx to a specifically reviewed version rather than using only a lower bound.
  2. Generate and commit a lock file that captures all transitive dependencies.
  3. Record cryptographic hashes and install with hash verification.
  4. Use a trusted, authenticated package index and disable unintended fallback indexes.
  5. Run dependency vulnerability and update checks as part of release maintenance.
  6. Test and deliberately approve dependency upgrades before changing the lock file.

A hash-locked requirements entry should follow this pattern:

text
python-pptx==REVIEWED_VERSION \
    --hash=sha256:REVIEWED_DISTRIBUTION_HASH

Installation can then enforce integrity:

bash
python3 -m pip install --require-hashes -r requirements.txt
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The manifest describes a PPT generation skill, but the detected behavior includes analyzing existing PowerPoint content, extracting slide text/structure, and writing a JSON catalog instead of only generating decks from provided XML/prompts. This mismatch is dangerous because it can conceal data extraction or unintended processing of proprietary template content, preventing users and reviewers from accurately assessing what the skill actually does.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill advertises file read/write capability through its effective behavior but does not declare any explicit tool scope or permissions in the manifest. That makes the trust boundary unclear and can lead to overbroad filesystem access being granted implicitly, which is risky for a skill that handles templates and writes output files.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The handler builds output_path as skill_root / output_filename using caller-controlled input without validating that the final path stays within the skill directory. In Python, absolute paths override the base path and relative traversal such as ../../ can escape it, allowing arbitrary file overwrite wherever the process has write access. In an agent setting, that exceeds the expected scope of 'generate a PPT' and can be used to clobber application files, user files, or other artifacts.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The XML content mixes Chinese slide titles and labels with English titles and subtitles, indicating an implicit locale choice in the generated presentation content. There is no natural-language indication that the user can choose the output language or that the bilingual/mixed-language format is required for a region-specific purpose.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dependency is specified with a lower-bound range (python-pptx>=0.6.23) rather than being pinned to an exact version, which makes builds non-reproducible and can pull in newly published upstream releases without review. In a skill that generates PowerPoint decks, this is not directly dangerous by itself, but it increases supply-chain risk because a compromised or breaking future release of python-pptx could be installed automatically.

Content

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

text
python-pptx>=0.6.23

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The code hardcodes the title fallback text "目录", which forces Chinese output in at least one generated slide element regardless of user preference. The file does not offer locale selection or document that the tool is intentionally region-specific.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The skill saves a generated presentation to a user-controlled path via prs.save(str(output_path)), which is a file write operation. Although this is part of the generator's functionality, there is no confirmation prompt, comment/docstring warning, or user-facing disclosure near the write path itself about overwriting or creating files.

Content

No source excerpt is available for this finding.