CVE-2025-64712: Verified Repro With Script Download
CVE-2025-64712: Unstructured has Path Traversal via Malicious MSG Attachment that Allows Arbitrary File Write
CVE-2025-64712 is verified against unstructured · pypi. Affected versions: <=0.18.17. Fixed in 0.18.18. Vulnerability class: Path Traversal. This critical reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00084.
What Is CVE-2025-64712?
CVE-2025-64712 is a path-traversal vulnerability in the unstructured Python library's partition_msg function that allows an attacker to write or overwrite arbitrary files on the filesystem via a malicious MSG attachment. Pruva reproduced it (reproduction REPRO-2026-00084).
CVE-2025-64712 Severity & CVSS Score
CVE-2025-64712 is rated critical severity, with a CVSS base score of 9.8 out of 10.
Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.
Affected unstructured Versions
unstructured · pypi versions <=0.18.17 are affected.
How to Reproduce CVE-2025-64712
pruva-verify REPRO-2026-00084 curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00084/artifacts/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh Proof of Reproduction for CVE-2025-64712
Reproduced by Pruva's autonomous agents — 193 tool calls over 5 min. Full root-cause analysis and the complete transcript are below.
How the agent worked
Root Cause and Exploit Chain for CVE-2025-64712
Summary
The unstructured library’s partition_msg attachment handling writes attachment payloads to a temporary directory using the attachment filename directly. When an MSG attachment filename contains path traversal sequences (e.g., ../../../../tmp/pwned), os.path.join(tmp_dir, filename) escapes the temporary directory and writes to arbitrary filesystem locations. This occurs before any attachment partitioning, enabling arbitrary file overwrite when process_attachments=True.
Impact
- Package/component affected:
unstructuredpartitioning of MSG files (unstructured.partition.msg/_AttachmentPartitioner). - Affected versions: <= 0.18.17 (tested on 0.18.15). Patched in 0.18.18 per advisory.
- Risk level and consequences: Critical. Arbitrary file overwrite on the host (e.g., overwriting configs/cron/python packages), potentially leading to code execution or data loss.
Root Cause
_AttachmentPartitioner._iter_elements() in unstructured/partition/msg.py uses:
detached_file_path = os.path.join(tmp_dir_path, self._attachment_file_name)
with open(detached_file_path, "wb") as f:
f.write(self._file_bytes)
self._attachment_file_name comes from oxmsg attachment file_name (PID_ATTACH_LONG_FILENAME) and is not sanitized. When it contains ../ sequences, os.path.join produces a path outside the intended temp directory, enabling traversal and arbitrary file write. The fix in 0.18.18 likely sanitizes or strips path separators before writing.
Reproduction Steps
- Run
repro/reproduction_steps.sh. - The script clones unstructured, checks out tag 0.18.15, installs deps, copies
fake-email-multiple-attachments.msg, and overwrites the attachment filename stream (__substg1.0_3707001F) with../../../../tmp/pwned(UTF-16LE) usingolefile. - It calls
partition_msg(..., process_attachments=True), which writes the attachment payload to/tmp/pwnedbefore failing on missing image deps. - Expected evidence:
/tmp/pwnedexists and has non-zero size after the call.
Evidence
- Script output (from
repro/reproduction_steps.sh):partition error: <class 'ImportError'> partition_image() is not available.../tmp/pwned exists: True/tmp/pwned size: 96226
- Environment: Ubuntu container with Python venv; unstructured 0.18.15 installed from local repo; python-oxmsg 0.0.2.
Recommendations / Next Steps
- Fix: sanitize attachment filenames by stripping path separators or enforcing basename before writing to temp dir.
- Upgrade: update to unstructured >= 0.18.18.
- Tests: add regression test that attachment filenames containing
../are sanitized and cannot escape temp directory.
Additional Notes
- Repro script is idempotent: it overwrites the same test MSG and removes
/tmp/pwnedbefore running. - Even when attachment partitioning fails due to missing optional image dependencies, the vulnerable file write already occurred, so evidence is still produced.
CVE-2025-64712 Reproduction Transcript
The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.
Full session Replay every step — scrub the timeline or play it back.
git clone https://github.com/Unstructured-IO/unstructured.git /data/pruva/runs/0d8207ce-6bfc-43e4-8f63-3d1fe63d5fa9/unstructuredCloning into '/data/pruva/runs/0d8207ce-6bfc-43e4-8f63-3d1fe63d5fa9/unstructured'...
git -C /data/pruva/runs/0d8207ce-6bfc-43e4-8f63-3d1fe63d5fa9/unstructured checkout v0.18.17error: pathspec 'v0.18.17' did not match any file(s) known to git
git -C /data/pruva/runs/0d8207ce-6bfc-43e4-8f63-3d1fe63d5fa9/unstructured tag --list | tail -n 200.7.5 0.7.6 0.7.7 0.7.8 0.7.9 0.8.0 0.8.1 0.8.1-docs-rebuild
git -C /data/pruva/runs/0d8207ce-6bfc-43e4-8f63-3d1fe63d5fa9/unstructured tag --list | grep 0.180.10.18 0.18.1 0.18.10 0.18.11 0.18.12 0.18.13 0.18.14 0.18.15
git -C /data/pruva/runs/0d8207ce-6bfc-43e4-8f63-3d1fe63d5fa9/unstructured checkout 0.18.17error: pathspec '0.18.17' did not match any file(s) known to git
git -C /data/pruva/runs/0d8207ce-6bfc-43e4-8f63-3d1fe63d5fa9/unstructured checkout 0.18.15Note: switching to '0.18.15'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by switching back to a branch. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -c with the switch command. Example:
Artifacts and Evidence for CVE-2025-64712
Scripts, logs, diffs, and output captured during the reproduction.
No artifacts available
How to Fix CVE-2025-64712
Upgrade unstructured · pypi to 0.18.18 or later.
FAQ: CVE-2025-64712
How does the malicious-MSG-attachment file-write attack work?
Which unstructured versions are affected by CVE-2025-64712, and where is it fixed?
How severe is CVE-2025-64712?
How can I reproduce CVE-2025-64712?
References for CVE-2025-64712
Authoritative sources for CVE-2025-64712 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.