VYPR
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.

PackageAffected versionsPatched versions
niceguiPyPI
< 3.4.03.4.0

Affected products

1

Patches

1
a1b89e2a24e1

Merge commit from fork

https://github.com/zauberzeug/niceguiEvan ChanDec 8, 2025via ghsa
2 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

News mentions

0

No linked articles in our index yet.