Skip to content

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.

REPRO-2026-00084 unstructured · pypi Path Traversal Feb 13, 2026 CVE entry ↗ .txt
Severity
CRITICAL
CVSS
9.8
Reproduced in
4m 50s
Tool calls
193
01 · Overview

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).

02 · Severity & CVSS

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 threat level
9.8 / 10 CVSS base
Weakness CWE-22 — Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.

03 · Affected Versions

Affected unstructured Versions

unstructured · pypi versions <=0.18.17 are affected.

How to Reproduce CVE-2025-64712

$ pruva-verify REPRO-2026-00084
or curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00084/artifacts/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

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 285 events · 193 tool calls · 5 min
5 minDuration
193Tool calls
84Reasoning steps
285Events
3Dead-ends
Agent activity over 5 min
Support
19
Repro
150
Variant
111
0:0004:50

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: unstructured partitioning 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

  1. Run repro/reproduction_steps.sh.
  2. 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) using olefile.
  3. It calls partition_msg(..., process_attachments=True), which writes the attachment payload to /tmp/pwned before failing on missing image deps.
  4. Expected evidence: /tmp/pwned exists 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/pwned before 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.

Event 1/40
0:002:53
0:00
session startedgpt-4o · GHSA-gm8q-m8mv-jj5m · 0d8207ce
0:03
0:07
web search
0:09
0:17
web search
0:19
0:43
0:51
0:52
extract_facts
no facts extracted
0:55
0:55
supportrepro
1:09
1:12
web search
1:15
1:19
1:24
1:25
1:27
1:36
1:36
1:37
1:39
1:50
1:50
1:53
web search
2:00
2:14
$git clone https://github.com/Unstructured-IO/unstructured.git /data/pruva/runs/0d8207ce-6bfc-43e4-8f63-3d1fe63d5fa9/unstructured
13.7s
Cloning into '/data/pruva/runs/0d8207ce-6bfc-43e4-8f63-3d1fe63d5fa9/unstructured'...
2:18
$git -C /data/pruva/runs/0d8207ce-6bfc-43e4-8f63-3d1fe63d5fa9/unstructured checkout v0.18.17
0.5s
error: pathspec 'v0.18.17' did not match any file(s) known to git
2:21
$git -C /data/pruva/runs/0d8207ce-6bfc-43e4-8f63-3d1fe63d5fa9/unstructured tag --list | tail -n 20
0.4s
0.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
2:23
$git -C /data/pruva/runs/0d8207ce-6bfc-43e4-8f63-3d1fe63d5fa9/unstructured tag --list | grep 0.18
0.1s
0.10.18
0.18.1
0.18.10
0.18.11
0.18.12
0.18.13
0.18.14
0.18.15
2:26
$git -C /data/pruva/runs/0d8207ce-6bfc-43e4-8f63-3d1fe63d5fa9/unstructured checkout 0.18.17
0.2s
error: pathspec '0.18.17' did not match any file(s) known to git
2:29
$git -C /data/pruva/runs/0d8207ce-6bfc-43e4-8f63-3d1fe63d5fa9/unstructured checkout 0.18.15
0.6s
Note: 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:
2:32
2:33
2:37
2:40
2:42
2:45
2:50
2:53

Artifacts and Evidence for CVE-2025-64712

Scripts, logs, diffs, and output captured during the reproduction.

No artifacts available

08 · How to Fix

How to Fix CVE-2025-64712

Upgrade unstructured · pypi to 0.18.18 or later.

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2025-64712 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2025-64712

How does the malicious-MSG-attachment file-write attack work?

An attacker crafts an MSG file containing an attachment whose filename includes path-traversal sequences such as ../../../../tmp/pwned. When the library processes the message with process_attachments=True, os.path.join joins that filename onto the temp directory, escapes it, and writes the attachment's raw bytes to the attacker-chosen path — before any attachment partitioning even occurs.

Which unstructured versions are affected by CVE-2025-64712, and where is it fixed?

Versions <= 0.18.17 are affected (tested on 0.18.15); it is fixed in 0.18.18.

How severe is CVE-2025-64712?

The root-cause analysis rates it critical — arbitrary file overwrite on the host (for example, overwriting configs, cron jobs, or installed Python packages), potentially leading to code execution or data loss.

How can I reproduce CVE-2025-64712?

Download the verified script from this page and run it in an isolated environment against unstructured <= 0.18.17 (tested on 0.18.15). It builds a malicious MSG file with an attachment filename containing ../ traversal sequences, runs partition_msg with process_attachments=True, and shows the attachment being written outside the intended temp directory, then confirms 0.18.18 blocks it.
11 · References

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.