High severityNVD Advisory· Published Dec 9, 2025· Updated Dec 10, 2025
NiceGUI Path Traversal Vulnerability in app.add_media_files() Allows Arbitrary File Reading
CVE-2025-66645
Description
NiceGUI is a Python-based UI framework. Versions 3.3.1 and below are vulnerable to directory traversal through the App.add_media_files() function, which allows a remote attacker to read arbitrary files on the server filesystem. This issue is fixed in version 3.4.0.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
niceguiPyPI | < 3.4.0 | 3.4.0 |
Affected products
1- Range: < 3.4.0
Patches
12 files changed · +26 −2
nicegui/app/app.py+3 −2 modified@@ -274,8 +274,9 @@ def add_media_files(self, url_path: str, local_directory: Union[str, Path]) -> N """ @self.get(url_path.rstrip('/') + '/{filename:path}') # NOTE: prevent double slashes in route pattern def read_item(request: Request, filename: str, nicegui_chunk_size: int = 8192) -> Response: - filepath = Path(local_directory) / filename - if not filepath.is_file(): + local_dir = Path(local_directory).resolve() + filepath = (local_dir / filename).resolve() + if not filepath.is_relative_to(local_dir) or not filepath.is_file(): raise HTTPException(status_code=404, detail='Not Found') return get_range_response(filepath, request, chunk_size=nicegui_chunk_size)
tests/test_serving_files.py+23 −0 modified@@ -15,6 +15,14 @@ VIDEO_FILE.write_bytes(b'\x00' * 2000) # dummy video file large enough to be streamed +@pytest.fixture +def secret_file(): + secret_path = Path(TEST_DIR) / '.env' + secret_path.write_text('TOP SECRET DATA') + yield secret_path + secret_path.unlink(missing_ok=True) + + def assert_video_file_streaming(path: str) -> None: with httpx.Client() as http_client: r = http_client.get( @@ -39,6 +47,21 @@ def page(): assert_video_file_streaming('/media/test.mp4') +def test_media_files_against_path_traversal(screen: Screen, secret_file): + app.add_media_files('/media', Path(TEST_DIR) / 'media') + + @ui.page('/') + def page(): + ui.label('Hello, world!') + + screen.open('/') + + with httpx.Client() as http_client: + r = http_client.get(f'http://localhost:{Screen.PORT}/media/%2e%2e/.env') + assert 'TOP SECRET DATA' not in r.text + assert r.status_code == 404 + + def test_adding_single_media_file(screen: Screen): url_path = app.add_media_file(local_file=VIDEO_FILE)
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-hxp3-63hc-5366ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-66645ghsaADVISORY
- github.com/zauberzeug/nicegui/commit/a1b89e2a24e1911a40389ace2153a37f4eea92a9ghsax_refsource_MISCWEB
- github.com/zauberzeug/nicegui/security/advisories/GHSA-hxp3-63hc-5366ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.