T09 · Insecure Skill Coding Practices
- Location
scripts/fill_template.py:61- Finding
Untrusted DOCX Package Content Is Preserved Without Validation
- Content
View full analysis
Vulnerability Details
File Location:
scripts/fill_template.py, lines 61–68
Vulnerability Type: Unvalidated preservation of active and externally referenced DOCX content
Risk Level: MediumVulnerable Code:
python with zipfile.ZipFile(template_path, "r") as zin, zipfile.ZipFile(tmp, "w", compression=zipfile.ZIP_DEFLATED) as zout: # copy all first for item in zin.infolist(): data = zin.read(item.filename) zout.writestr(item, data) # patch in-place by rewriting the same members patch_fn(zin, zout)Technical Analysis
A DOCX file is an OOXML ZIP package that may contain more than visible document text and formatting. It can include external relationships, embedded or attached objects, OLE content, ActiveX components, custom XML, and content associated with headers, footers, or other document parts.
The implementation copies every entry from the input package into the output without inspecting its type, relationship mode, destination, or necessity. It subsequently modifies only selected document parts. Consequently, potentially dangerous or privacy-sensitive content in an attacker-controlled template can survive unchanged in the generated output.
This behavior exceeds the minimum package access required to preserve ordinary formatting. The script does not enforce an allowlist of expected OOXML parts, reject external relationship targets, or remove active content and embedded objects.
The same archive-writing design also appends patched versions of existing XML members after first copying the originals. This can create duplicate ZIP member names for
word/document.xmlandword/_rels/document.xml.rels. Different consumers may select different duplicate entries, making validation and output behavior parser-dependent.Attack Path
- An attacker creates or supplies a DOCX template containing an external relationship, embedded object, attached package, or ...[truncated 1348 chars]
- Remediation
View remediation
Remediation Suggestions
- Treat input templates as untrusted ZIP packages and validate every archive member before copying it.
- Define an explicit allowlist of OOXML parts required for document text, styles, themes, numbering, fonts, images, headers, footers, and section formatting.
- Parse all relationship files and reject or remove relationships with
TargetMode="External"unless explicitly required and approved. - Reject or strip macros, ActiveX controls, OLE objects, embedded packages, attached files, and unexpected binary members.
- Validate relationship targets to ensure they resolve only to permitted internal package paths.
- Rewrite the archive in a single pass: skip members that will be patched and write exactly one final version of each member. Reject duplicate member names in the input.
- Apply archive resource limits, including maximum member count, compressed size, uncompressed size, and compression ratio, when accepting untrusted templates.
- Document the trust boundary clearly and warn users not to process templates from untrusted sources until comprehensive OOXML sanitization is implemented.
- Add automated tests using templates containing external relationships, embedded objects, duplicate ZIP entries, and unexpected package members to verify that unsafe content is rejected or removed.
