Back to skill

Security audit

ppt2fig Export

Security checks for vulnerabilities and agentic risk

Overview

This skill appears to be a legitimate presentation-to-PDF converter, but it installs and runs an unpinned Windows executable and has overly broad executable lookup behavior.

Review before installing, especially on Windows. Only install if you trust the ppt2fig GitHub release source, and prefer a version-pinned, checksum-verified binary or a trusted local ppt2fig installation. Avoid running it from shared or untrusted workspaces where a dist/ppt2fig-cli.exe file could be planted.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:5
Finding

Mutable External Executable Is Downloaded and Run Without Integrity Verification

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:5
Vulnerability Type: Unverified remote payload retrieval and supply-chain risk
Risk Level: High

Vulnerable Code Snippet:

yaml
metadata: {"openclaw":{"homepage":"https://github.com/elliottzheng/ppt2fig","skillKey":"ppt2fig-export","always":true,"os":["win32"],"install":[{"id":"ppt2fig-cli-win64","kind":"download","os":["win32"],"url":"https://github.com/elliottzheng/ppt2fig/releases/latest/download/ppt2fig-cli.exe","targetDir":"~/.openclaw/tools/ppt2fig-export","label":"Download ppt2fig CLI for Windows"}]}}

Technical Analysis

The installation configuration downloads a native Windows executable from the external, mutable latest GitHub release URL. The Skill does not pin a release version, specify a cryptographic checksum, or require verification of a trusted publisher signature.

Consequently, the code that is eventually executed can change after the Skill has been reviewed. HTTPS protects the download in transit but does not protect against compromise of the publisher account, repository, release workflow, or upstream asset. Because the downloaded object is a native executable, a compromised release can run arbitrary code rather than being limited to presentation conversion.

Downloading a converter is relevant to the declared functionality, but accepting an unpinned executable without integrity validation exceeds the minimum safe trust required to implement that functionality.

Attack Path

  1. An attacker compromises the upstream repository owner, release workflow, token, or GitHub account.
  2. The attacker publishes or replaces ppt2fig-cli.exe in the release targeted by the mutable latest URL.
  3. OpenClaw installs the executable into ~/.openclaw/tools/ppt2fig-export.
  4. The helper script identifies that executable as its first candidate.
  5. A normal presentation-conversion request executes the attacker-controlled binary.
  6. The binar ...[truncated 781 chars]
Remediation
View remediation

Remediation Suggestions

  1. Replace the mutable latest URL with an immutable, explicitly versioned release URL.
  2. Record an audited SHA-256 or stronger digest in the Skill and verify it before installation or execution.
  3. Require a valid Windows Authenticode signature from an explicitly trusted publisher where available.
  4. Fail closed if the hash, signature, expected filename, or version does not match.
  5. Perform release upgrades through explicit reviewed changes rather than automatically following latest.
  6. Prefer installation through a trusted package repository with provenance and reproducible-build metadata.
  7. Execute the converter with only the filesystem and network access required for conversion, ideally in a sandbox without credentials or unrestricted outbound network access.

T07 · Tool Hijacking and Spoofing

Warning
Location
scripts/run_ppt2fig.py:6
Finding

Executable Discovery Allows Local Binary Substitution

Content
View full analysis

Vulnerability Details

File Location: scripts/run_ppt2fig.py:6-26
Vulnerability Type: Local tool hijacking through untrusted executable search paths
Risk Level: Medium

Vulnerable Code Snippet:

python
def find_program():
    candidates = [
        str(Path.home() / ".openclaw" / "tools" / "ppt2fig-export" / "ppt2fig-cli.exe"),
        str(Path.home() / ".openclaw" / "tools" / "ppt2fig-export" / "ppt2fig-cli-upx.exe"),
        shutil.which("ppt2fig"),
        shutil.which("ppt2fig-cli"),
        str(Path.cwd() / "dist" / "ppt2fig-cli-upx.exe"),
        str(Path.cwd() / "dist" / "ppt2fig-cli.exe"),
        str(Path(__file__).resolve().parents[3] / "dist" / "ppt2fig-cli-upx.exe"),
        str(Path(__file__).resolve().parents[3] / "dist" / "ppt2fig-cli.exe"),
    ]
    for candidate in candidates:
        if candidate and Path(candidate).exists():
            return [candidate]
    return [sys.executable, "-m", "ppt2fig"]


def main():
    command = find_program() + sys.argv[1:]
    completed = subprocess.run(command)

Technical Analysis

The launcher accepts executables from the current working directory's dist subdirectory and from an ancestor-relative dist directory. Selection requires only that the path exists. It does not verify that the candidate is a regular file, is owned by a trusted account, resides in a controlled installation directory, matches an approved cryptographic hash, or has a trusted code signature.

If the preferred OpenClaw installation and PATH candidates are unavailable, an attacker who can write to one of these local directories can plant a malicious executable with an expected filename. The helper will then execute it as though it were the legitimate converter.

subprocess.run receives an argument list and does not enable a shell, so the reviewed code does not expose direct shell-command injection through forwarded arguments. The issue is execut ...[truncated 1534 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the current-working-directory and ancestor-relative dist fallbacks.
  2. Resolve the converter only from a dedicated installation directory whose permissions prevent modification by untrusted users or workspaces.
  3. Validate the selected binary against an approved SHA-256 digest or trusted publisher signature before every execution.
  4. Require the candidate to be a regular file and reject symbolic links, reparse points, and paths that escape the approved installation directory.
  5. If PATH lookup remains supported, resolve the final canonical path and enforce an allowlist of trusted installation roots.
  6. Fail safely with a clear installation error rather than executing an unverified local fallback.
  7. Where practical, use the reviewed Python module from a locked environment instead of dynamically selecting arbitrary native executables.
Vulnerability Patterns
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (2)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill instructs the agent to run shell commands (ppt2fig, ppt2fig-cli, and a Python wrapper) against user-supplied file paths, but it does not declare any permissions or allowed-tools scope. That creates an authorization gap where the agent may invoke shell capability without an explicit policy boundary, increasing the risk of unintended command execution or unsafe handling of untrusted paths and arguments.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/run_ppt2fig.py (reported line 26)May include surrounding context.

python
def main():
    command = find_program() + sys.argv[1:]
    completed = subprocess.run(command)
    raise SystemExit(completed.returncode)

Static analysis

No suspicious patterns detected.