Lucene search
K

📄 Dash-Uploader 0.7.0a2 Path Traversal

🗓️ 08 May 2026 00:00:00Reported by Muhammad Fitri Bin Mohd SultanType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 45 Views

Unauthenticated path traversal in dash-uploader enables arbitrary file writes and code execution.

Related
Code
ReporterTitlePublishedViews
Family
GithubExploit
Exploit for CVE-2026-38360
7 May 202614:59
githubexploit
GithubExploit
Exploit for CVE-2026-38361
7 May 202620:32
githubexploit
GithubExploit
Exploit for CVE-2026-38360
7 May 202620:32
githubexploit
ATTACKERKB
CVE-2026-38361
8 May 202600:00
attackerkb
ATTACKERKB
CVE-2026-38360
8 May 202600:00
attackerkb
Circl
CVE-2026-38360
7 May 202619:00
circl
Circl
CVE-2026-38361
7 May 202615:00
circl
CNNVD
dash-uploader 路径遍历漏洞
8 May 202600:00
cnnvd
CNNVD
dash-uploader 资源管理错误漏洞
8 May 202600:00
cnnvd
CVE
CVE-2026-38360
8 May 202600:00
cve
Rows per page
# CVE-2026-38360: Path Traversal in dash-uploader
    
    [![CVE](https://img.shields.io/badge/CVE-2026--38360-red?style=for-the-badge)](https://www.cve.org/CVERecord?id=CVE-2026-38360)
    [![CWE](https://img.shields.io/badge/CWE-22-orange?style=for-the-badge)](https://cwe.mitre.org/data/definitions/22.html)
    [![Severity](https://img.shields.io/badge/Severity-Critical-red?style=for-the-badge)](#)
    [![Patch](https://img.shields.io/badge/Patch-None-black?style=for-the-badge)](#mitigation)
    [![Auth](https://img.shields.io/badge/Auth-None_required-red?style=for-the-badge)](#attack-vectors)
    [![Version](https://img.shields.io/badge/dash--uploader-0.6.1-blue?style=for-the-badge)](https://pypi.org/project/dash-uploader/)
    [![PyPI Downloads](https://img.shields.io/badge/PyPI%20downloads-28K%2Fmonth-blue?style=for-the-badge)](https://pepy.tech/project/dash-uploader)
    [![Total Downloads](https://img.shields.io/badge/Total%20downloads-733.08K-blue?style=for-the-badge)](https://pepy.tech/project/dash-uploader)
    [![License](https://img.shields.io/pypi/l/dash-uploader?style=for-the-badge)](https://pypi.org/project/dash-uploader/)
    
    Unauthenticated path traversal in [`fohrloop/dash-uploader`](https://github.com/fohrloop/dash-uploader) (Python, PyPI) allowing arbitrary file write, leading to (but not limited to) **Remote Code Execution (RCE)**, application source code overwrite, stored XSS, and persistent backdoor installation.
    
    ### ⚠️ No patch is available, and none will ever be released
    
    The repository was [archived on 2025-07-19](https://github.com/fohrloop/dash-uploader/issues/153) with no active maintainer. Every published version (`0.1.0` through `0.7.0a2`) is affected and will remain so. The package still pulls roughly 28,000 monthly downloads.
    
    Anyone running `dash-uploader` in production must apply a mitigation themselves. The recommended fix is to migrate to Plotly Dash's built-in `dcc.Upload` component. See [Mitigation](#mitigation) for full options.
    
    | | |
    |---|---|
    | **CVE ID** | CVE-2026-38360 |
    | **Vulnerability** | Path Traversal (CWE-22) |
    | **CVSS 3.1** | 9.8 / Critical (`AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H`) |
    | **Product** | dash-uploader |
    | **Affected versions** | `0.1.0` through `0.7.0a2` (all 18 releases) |
    | **Fixed version** | none (project archived 2025-07-19) |
    | **Attack vector** | Remote, unauthenticated |
    | **Discoverer** | Muhammad Fitri Bin Mohd Sultan |
    | **Assigned by** | MITRE, 2026-05-07 |
    | **Related** | [CVE-2026-38361](https://github.com/a1ohadance/CVE-2026-38361) (DoS in same library) |
    
    ## Description
    
    Three user-controlled parameters from `request.form.get()` in `dash_uploader/httprequesthandler.py` are passed directly to `os.path.join()` and `os.makedirs()` without any sanitization or validation:
    
    1. **`upload_id`** (line 57 → line 161, `BaseHttpRequestHandler.get_temp_root`): controls the destination directory. An attacker can send `upload_id=../../../../usr/local/lib/python3.10/site-packages` and files are written to Python's package directory.
    
    2. **`resumableFilename`** (line 51 → line 108, `BaseHttpRequestHandler._post`): controls the final filename. An attacker can traverse out of the upload directory via the filename even with a legitimate `upload_id`.
    
    3. **`resumableIdentifier`** (line 54 → line 64, `BaseHttpRequestHandler._post`): used with `os.makedirs()` to create the temp directory. An attacker can create arbitrary directories anywhere on the filesystem.
    
    The upload endpoint (`/API/dash-uploader` by default) requires no authentication. The `http_request_handler` hook added in `v0.5.0` allows pre-request checks via `post_before()`, but the vulnerable `_post()` method reads all parameters directly from `request.form` after the hook returns. The hook cannot sanitize parameters before the library processes them. A developer who adds authentication via the hook is still vulnerable to path traversal from an authenticated user.
    
    ## Vulnerable code
    
    ```python
    # dash_uploader/httprequesthandler.py
    def _post(self):
        resumableFilename = request.form.get("resumableFilename", default="error", type=str)
        resumableIdentifier = request.form.get("resumableIdentifier", default="error", type=str)
        upload_id = request.form.get("upload_id", default="", type=str)
        ...
        temp_root = self.get_temp_root(upload_id)                          # upload_id flows in here
        temp_dir = os.path.join(temp_root, resumableIdentifier)            # raw user input -> os.path.join
        if not os.path.isdir(temp_dir):
            os.makedirs(temp_dir)                                          # raw user input -> os.makedirs
    
    def get_temp_root(self, upload_id):
        return os.path.join(self.upload_folder, upload_id)                 # no sanitization: ../../ escapes upload_folder
    ```
    
    Three independent traversal sinks share the same root cause: form values reach `os.path.join` and `os.makedirs` with no validation.
    
    ## Attack vectors
    
    An unauthenticated remote attacker sends an HTTP POST multipart request to the upload endpoint. By injecting path traversal sequences (`../`) into the `upload_id` form parameter, the attacker controls the destination directory for the uploaded file. For example, `upload_id=../../../../usr/local/lib/python3.10/site-packages` writes files to Python's package directory, enabling RCE on the next interpreter startup via `.pth` auto-execution.
    
    No authentication, session token, or CSRF token is required. Two additional parameters (`resumableFilename` and `resumableIdentifier`) provide independent traversal vectors through the same endpoint. The default library configuration as shown in the official quickstart documentation is exploitable with a single `curl` command.
    
    ## Impact
    
    Arbitrary file write to any directory writable by the server process. This translates to **Remote Code Execution (RCE)** through several well-known primitives:
    
    **RCE primitives**
    
    - Python `.pth` file dropped into `site-packages`. Executes attacker-supplied code on the next interpreter startup.
    - `sitecustomize.py` or `usercustomize.py` injection. Executes on every Python startup.
    - Overwriting an importable Python module in the application's package directory. Executes on next import or worker recycle.
    - Overwriting the WSGI/ASGI entry point (e.g. `app.wsgi`, `wsgi.py`). Executes on next worker reload.
    - Cron drop-in (`/etc/cron.d/`, `/etc/cron.hourly/`, user crontab spool) when the process has the necessary privileges. Scheduled execution.
    - Systemd unit or user-unit drop-in (`/etc/systemd/system/`, `~/.config/systemd/user/`). Executes on next service start or reboot.
    - `/etc/ld.so.preload` injection when the process runs as root. Preloads attacker code into every subsequent binary execution.
    - Shell startup file overwrite (`~/.bashrc`, `~/.profile`, `~/.bash_profile`). Executes on next interactive login of the app user.
    - `~/.ssh/authorized_keys` append. Grants persistent SSH access to the host as the app user.
    
    **Web-tier impact**
    
    - Stored cross-site scripting on the host domain by overwriting served JavaScript (for example, Dash framework JS in `site-packages`), affecting every user on every page load until the application is restarted
    - Application source code overwrite (a silent, persistent backdoor that survives normal deploys when the deploy mechanism does not fully overwrite the affected paths)
    
    **Filesystem impact**
    
    - Arbitrary directory creation anywhere the process can reach, via `os.makedirs()` with the unsanitized `resumableIdentifier` parameter (usable for inode exhaustion or for staging writes into nonexistent directory trees)
    - Cross-user file replacement in shared upload directories, leading to data poisoning between tenants of the same application
    
    ## Affected component
    
    - `dash_uploader/httprequesthandler.py`
    - `BaseHttpRequestHandler.get_temp_root()`
    - `BaseHttpRequestHandler._post()`
    
    ## Mitigation
    
    ### ⚠️ No patch is available, and the project is archived
    
    Options for currently-deployed users, in order of preference:
    
    1. **Migrate to `dcc.Upload`**, the official upload component shipped with Plotly Dash. Files arrive at the callback as a base64 string; no filesystem-writing handler is exposed and no client-controlled destination path exists, so the bug class here does not apply. Best suited to small and medium files. For very large uploads, see item 2.
    2. **Roll a small Flask upload handler** using `werkzeug.utils.secure_filename()` and a hardcoded server-side destination directory. Never accept client-supplied `upload_id`, filename, or identifier values as path components.
    3. **If continuing to use dash-uploader**, place the upload endpoint behind authentication AND validate `upload_id`, `resumableFilename`, and `resumableIdentifier` against a strict allowlist (e.g., UUIDs only) at a layer that rewrites or rejects the request before the library handler sees it. The library's `http_request_handler` hook does NOT prevent the traversal because parameters are read from `request.form` after the hook returns; sanitization must happen above the library.
    4. **At the reverse-proxy or WAF layer**, reject any request to the upload endpoint where any form field contains `..`, encoded variants (`%2e%2e`, `..%2f`, `%2e%2e%2f`), or absolute paths.
    
    ## Disclosure timeline
    
    | Date | Event |
    |---|---|
    | 2026-03-17 | Vulnerability discovered during security research on a production deployment. |
    | 2026-03-19 | CVE request submitted to MITRE. |
    | 2026-05-07 | CVE-2026-38360 assigned by MITRE. |
    | 2026-05-07 | Public advisory published. |
    
    ## Package context
    
    - Approximately 28,000 monthly downloads on PyPI (27,756 in the 30 days preceding 2026-05-07, with sustained daily volume despite repository archival). Source: [pypistats.org](https://pypistats.org/packages/dash-uploader).
    - Latest published version: `0.6.1` (stable line). Pre-releases extend to `0.7.0a2`.
    - Required dependency: `dash`. Optional dependency: `pyyaml`. License: MIT.
    - 11 dependent packages, 6 dependent repositories.
    - 153 GitHub stars.
    - Repository archived 2025-07-19 ([Issue #153](https://github.com/fohrloop/dash-uploader/issues/153)).
    - No prior CVEs (verified against NVD, GitHub Advisory Database, Snyk, OSV on 2026-03-19).
    
    ## References
    
    - https://github.com/fohrloop/dash-uploader
    - https://pypi.org/project/dash-uploader/
    - https://pypistats.org/packages/dash-uploader
    - https://github.com/fohrloop/dash-uploader/blob/stable/dash_uploader/httprequesthandler.py
    - https://github.com/fohrloop/dash-uploader/blob/dev/dash_uploader/httprequesthandler.py
    - https://github.com/fohrloop/dash-uploader/issues/153
    - https://cwe.mitre.org/data/definitions/22.html
    
    ## Discoverer
    
    Muhammad Fitri Bin Mohd Sultan

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

08 May 2026 00:00Current
5.8Medium risk
Vulners AI Score5.8
CVSS 3.17.5 - 9.8
EPSS0.13567
SSVC
45