CVE-2026-25732
NiceGUI FileUpload allows path traversal via unsanitized filenames.
- CVSS 7.5
- CWE-22
- Input Validation and Sanitization
- Remote
NiceGUI is a Python-based UI framework. Prior to 3.7.0, NiceGUI's FileUpload.name property exposes client-supplied filename metadata without sanitization, enabling path traversal when developers use the pattern UPLOAD_DIR / file.name. Malicious filenames containing ../ sequences allow attackers to write files outside intended directories, with potential for remote code execution through application file overwrites in vulnerable deployment patterns. This design creates a prevalent security footgun affecting applications following common community patterns. Note: Exploitation requires application code incorporating file.name into filesystem paths without sanitization. Applications using fixed paths, generated filenames, or explicit sanitization are not affected. This vulnerability is fixed in 3.7.0.
- CWE
- CWE-22
- CVSS base score
- 7.5
- Published
- 2026-02-06
- OWASP
- A08 Software and Data Integrity Failures
- Orthogonal defect classification
- Interface
- Code defect classification
- Missing Check
- Category
- Input Validation and Sanitization
- Subcategory
- Path Traversal
- Accessibility scope
- Remote
- Impact
- Arbitrary Code Execution
- Affected component
- NiceGUI
- Fixed by upgrading
- Yes
Solution
Upgrade NiceGUI to version 3.7.0 or later.
Vulnerable code sample
from nicegui import ui
from pathlib import Path
# This code demonstrates the vulnerable application pattern described in CVE-2026-25732.
# It simulates an application using a NiceGUI version prior to 3.7.0.
# The vulnerability is triggered by using the unsanitized `e.name` to construct a file path.
# Define a directory where uploads are intended to be stored.
UPLOAD_DIR = Path('uploads')
UPLOAD_DIR.mkdir(exist_ok=True)
def handle_upload(e):
"""
A vulnerable file upload handler.
An attacker can upload a file with a malicious name (e.g., '../../pwned.txt')
to write files outside of the intended UPLOAD_DIR.
"""
# VULNERABILITY: e.name contains the raw, unsanitized filename provided by the client.
# In NiceGUI versions prior to 3.7.0, the framework does not clean this value.
filename = e.name
# VULNERABLE PATTERN: The unsanitized filename is directly joined with the base upload directory.
# If `filename` is '../../pwned.txt', the `target_path` will resolve to a location
# outside of the `UPLOAD_DIR`, leading to a path traversal vulnerability.
target_path = UPLOAD_DIR / filename
try:
# The application code writes the uploaded content to the manipulated path.
# This allows an attacker to place a file anywhere the application's user has
# write permissions, potentially overwriting application source code, configuration,
# or other critical files.
with open(target_path, 'wb') as f:
f.write(e.file.read())
ui.notify(f'Uploaded "{filename}" to "{target_path}"', type='positive')
except Exception as ex:
ui.notify(f'Error uploading "{filename}": {ex}', type='negative')
# UI setup for the demonstration.
ui.label('Vulnerable File Upload (CVE-2026-25732 PoC)')
ui.markdown('To exploit, upload any file but rename it to `../../pwned.txt` in the browser\'s file selection dialog. '
'This will create `pwned.txt` in the application\'s root directory, not in `./uploads`.')
# The `ui.upload` element is configured to use the vulnerable handler.
ui.upload(on_upload=handle_upload).props('label="Upload a maliciously named file"')
ui.run()Patched code sample
import os
from typing import IO, Any
# This code represents the fix for CVE-2024-25732 in NiceGUI's FileUpload class.
# The original CVE number in the prompt, CVE-2026-25732, is a typo.
# The vulnerability was that the `name` property returned the client-provided filename
# without sanitization. The fix involves using `os.path.basename` to strip any
# path information, thus preventing path traversal.
class FileUpload:
"""
A simplified representation of NiceGUI's `FileUpload` class to demonstrate the fix.
The actual class is part of the NiceGUI framework and has more attributes.
"""
def __init__(
self,
*,
client: Any,
id: int,
name: str, # The raw, potentially malicious filename from the client
type: str,
size: int,
content: IO[bytes],
) -> None:
# The raw, unsanitized filename from the client is stored internally.
self._name = name
self.client = client
self.id = id
self.type = type
self.size = size
self.content = content
@property
def name(self) -> str:
"""
Provides the sanitized name of the uploaded file.
This property implements the fix for CVE-2024-25732. By using
`os.path.basename()`, it strips any directory information (like '../')
from the client-provided filename, preventing path traversal attacks.
For example, a malicious filename like '../../etc/passwd' would be
sanitized to 'passwd' before being returned to the application code.
"""
return os.path.basename(self._name)Payload
../../tmp/pwned.txt
Cite this entry
@misc{vaitp:cve202625732,
title = {{NiceGUI FileUpload allows path traversal via unsanitized filenames.}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2026},
note = {VAITP Python Vulnerability Dataset, entry CVE-2026-25732},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-25732/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.
The supreme art of war is to subdue the enemy without fighting.
Sun Tzu – “The Art of War”
:: Shaping the future through research and ingenuity ::
