T09 · Insecure Skill Coding Practices
- Location
ooxml/scripts/unpack.py:16- Finding
Unbounded extraction of untrusted Office archives permits resource exhaustion
- Content
View full analysis
Vulnerability Details
File Location:
ooxml/scripts/unpack.py:16-17;ooxml/scripts/validation/base.py:890-891;ooxml/scripts/validation/docx.py:200-201;ooxml/scripts/validation/redlining.py:69-70
Vulnerability Type: Unbounded archive extraction and decompression bomb exposure
Risk Level: MediumComplete Vulnerable Code
Primary extraction path in
ooxml/scripts/unpack.py:16-17:python output_path.mkdir(parents=True, exist_ok=True) zipfile.ZipFile(input_file).extractall(output_path)Equivalent extraction in
ooxml/scripts/validation/redlining.py:69-70:python with zipfile.ZipFile(self.original_docx, "r") as zip_ref: zip_ref.extractall(temp_path)The same unrestricted
extractall()pattern is also present in:python # ooxml/scripts/validation/base.py:890-891 with zipfile.ZipFile(self.original_file, "r") as zip_ref: zip_ref.extractall(temp_path)python # ooxml/scripts/validation/docx.py:200-201 with zipfile.ZipFile(self.original_file, "r") as zip_ref: zip_ref.extractall(temp_dir)Technical Analysis
PPTX, DOCX, and XLSX files are ZIP archives. These extraction paths accept document archives and extract every member without first enforcing limits on:
- Total uncompressed size
- Per-member uncompressed size
- Number of archive members
- Compression ratio
- Available disk space
- Overall extraction time
A malicious Office file can contain highly compressible data that occupies little space in the uploaded archive but expands to a very large size. It can also contain an excessive number of small files, imposing substantial filesystem and CPU overhead.
Although temporary directories limit where several validation paths write their data, they do not prevent exhaustion of the filesystem containing the temporary directory. The standalone unpacking path writes into a caller-selected output directory and is similarly unbou ...[truncated 1138 chars]
- Remediation
View remediation
Remediation Suggestions
Replace direct
extractall()calls with a controlled extraction routine that:- Iterates through
ZipFile.infolist()before writing any member. - Rejects archives exceeding a conservative member-count limit.
- Rejects members exceeding a per-file uncompressed-size limit.
- Tracks and limits the cumulative uncompressed size.
- Rejects suspicious compression ratios.
- Verifies that each resolved destination remains beneath the intended extraction directory.
- Rejects absolute paths, parent-directory components, and unsupported link-like entries.
- Extracts incrementally while enforcing byte limits rather than trusting archive metadata alone.
- Applies process timeouts, filesystem quotas, and isolated temporary storage.
- Deletes partially extracted content after any validation or quota failure.
Apply the same hardened helper consistently in
unpack.py,validation/base.py,validation/docx.py, andvalidation/redlining.py.- Iterates through
