skills/pptx-posters/references/pptx_security.md
A presentation can be more than visible slide XML. A package can contain VBA, ActiveX, OLE objects, embedded files, external relationships, linked images, malformed XML, duplicate/traversing ZIP names, or highly compressed payloads.
Do not open an untrusted presentation or template to see whether it is safe. Opening is execution by a complex Office application and is outside these scripts.
This skill:
python-pptx presentation only;.pptm, .potx, .potm, .ppsx, .ppsm, legacy .ppt, or
arbitrary office package;.pptx as a bounded one-slide generated-poster ZIP/XML profile without
extraction;ECMA-376 defines Office Open XML vocabularies, representation, and packaging. ISO/IEC 29500-2:2021 defines Open Packaging Conventions, which combine parts and relationships into one package.
The inspector expects a standard macro-free PresentationML package with at least:
[Content_Types].xml_rels/.relsppt/presentation.xmlppt/_rels/presentation.xml.relsIt requires the standard macro-free presentation main content type. It resolves internal relationship targets against package parts.
Microsoft's supported-format list
identifies .pptm as a macro-enabled presentation containing VBA code. A .pptx
extension alone is not sufficient assurance, so the inspector also checks content
types, relationships, and package part names.
The inspector rejects:
vbaProject parts;.pptm and every non-.pptx extension;ppt/activeX, control properties, custom UI, and related relationships;ppt/embeddings and package relationships;Microsoft's Open XML OLE object documentation shows that PresentationML OLE objects can be embedded or linked. Neither is needed for a static poster and both are rejected.
An OPC relationship can target an internal package part or an external resource.
Microsoft's
OPC target-mode documentation
distinguishes the two. The strict policy rejects any relationship with
TargetMode="External".
This includes:
The policy is intentionally stricter than PowerPoint's feature set. The visible
poster may contain an https:// URL as plain text, and a local QR image may encode
that URL, but the PPTX does not create a clickable external relationship.
Internal targets are normalized relative to the source part, must remain inside the package, and must exist.
The inspector reads the central directory before selected XML:
These are defensive local policy limits, not ECMA/ISO or PowerPoint product limits. Adjusting them is a security decision and requires new tests.
The ZIP footer is read directly before Python's ZipFile constructs its member list.
Declared member count and central-directory size are therefore bounded before the
library materializes attacker-controlled entries.
The code never calls ZipFile.extract or extractall. Python's
zipfile documentation warns
that callers must prevent archive members from escaping the destination; not
extracting removes that path entirely.
Every bounded XML part and every relationship part is parsed. The strict generated profile requires UTF-8 XML; NUL, document-type, and entity declarations are rejected before parsing, including attempts to hide declarations in another encoding. Content types, relationship roots/IDs/target modes, the one-slide relationship, and internal target existence are checked explicitly.
The inspector does not:
The generator writes each approved picture description to PresentationML nonvisual
drawing properties (p:cNvPr descr). Microsoft's
NonVisualDrawingProperties documentation
describes this element and its drawing description property.
The inspector counts pictures with nonempty descriptions. Presence is not semantic quality; review alt text in PowerPoint.
The generator also uses the visible poster title as the native slide-title placeholder and writes the manifest language on text runs. The inspector reports title count and missing run-language metadata. These structural fields still require PowerPoint, screen-reader, and exported-PDF review. Longer descriptions remain approved native text elements in reading order rather than hidden package attachments.
python-pptx and its exact-pinned
lxml dependency; never load a user template.The temporary files are private and in the destination directory. Final publication uses a same-filesystem hard link that fails if the destination already exists.
For a third-party PPTX:
python -B scripts/inspect_pptx.py untrusted.pptx
If it reports a finding, quarantine or discard the file. Do not open it to remediate.
Even a clean report is not an antivirus verdict. The checker recognizes a deliberately small package profile; it cannot prove that every Office parser vulnerability or malicious payload is absent. Apply organizational malware scanning, sandboxing, Office Protected View, patching, and provenance controls as required.
Do not use an inspected third-party file as a generator template. This skill has no template-input feature.
These limits are design boundaries, not invitations to bypass the checks.