pptx
- Type
- Skill
- Scanned
- Oct 29, 2026
- Version
- ca45fc496a34
- Files read
- 56
This skill provides instructions, Python scripts, and XML schemas for creating, editing, converting, and validating PowerPoint (.pptx and .potx) presentations. The main risks are XML External Entity (XXE) expansion when validating untrusted presentation XML with lxml, unsafe archive extraction instructions in the skill prompt, and an LD_PRELOAD shim compiled to a predictable path in the system temporary directory.
What it can reach
- Files
- Reads, extracts, modifies, validates, and writes Office archives (.pptx, .potx, .docx), XML parts, PDFs, and slide thumbnail images on the local filesystem, as well as temporary files in the system temp directory.
- Shell commands
- Runs external commands including LibreOffice (soffice), pdftoppm, gcc (to compile a socket shim when Unix sockets are blocked), git diff, markitdown, and zip.
Findings
-
HighXML External Entity (XXE) resolution in lxml validation
skills/pptx/scripts/office/validators/base.py:167
BaseSchemaValidator and its subclasses parse XML and .rels files from unpacked Office documents using lxml.etree.parse() with default parser settings, which keep resolve_entities=True. Although modern lxml blocks remote network fetches by default, local file entities (such as file:/// paths) are still resolved. A crafted .pptx or .docx file can reference local files via XML entities and leak their contents into schema validation errors or text-check output read by the agent.
Fix: Pass a restricted parser such as lxml.etree.XMLParser(resolve_entities=False, no_network=True, load_dtd=False) to all lxml.etree.parse() calls, or parse untrusted XML with defusedxml.
-
MediumSkill instructions tell the agent to unpack archives with raw extractall
Although the codebase provides a safe_extract() helper in scripts/office/helpers/__init__.py to block path traversal and symlink entries, SKILL.md instructs the agent to run zipfile.ZipFile.extractall() directly on input decks. Unpacking a malicious .pptx archive this way can allow Zip Slip path traversal or symlink writes outside the unpacked directory.
Fix: Update the skill instructions to unpack archives using the safe_extract() helper in scripts/office/helpers rather than raw zipfile.extractall().
-
MediumPredictable LD_PRELOAD shared library path in shared temporary directory
skills/pptx/scripts/office/soffice.py:50
When AF_UNIX sockets are blocked, soffice.py compiles a C shim to a fixed filename in the system temporary directory (/tmp/lo_socket_shim.so), reuses the file without ownership or integrity verification if it already exists, and points LD_PRELOAD to it when launching LibreOffice. On a system where /tmp is shared with other users or untrusted processes, pre-creating this file allows arbitrary code execution.
Fix: Write and compile the shim inside a private, securely created temporary directory (such as tempfile.mkdtemp() with 0700 permissions) owned by the current user.
-
LowMissing path containment check in validate_file_references
skills/pptx/scripts/office/validators/base.py:364
In validate_file_references(), relationship targets from .rels files are resolved on disk without verifying that the resulting path stays inside self.unpacked_dir. A crafted .rels file using ../ sequences can probe whether arbitrary files exist on the host filesystem based on whether a broken reference error is reported.
Fix: Resolve relationship targets using the opc_target() helper or check target_path.is_relative_to(self.unpacked_dir.resolve()) before testing whether the file exists.